Merge ~paride/curtin:20.1-29-g81144052-0ubuntu1 into curtin:ubuntu/devel
- Git
- lp:~paride/curtin
- 20.1-29-g81144052-0ubuntu1
- Merge into ubuntu/devel
Proposed by
Paride Legovini
Status: | Merged |
---|---|
Merged at revision: | 602618759f4ab30847599de23b598339a1c99ebc |
Proposed branch: | ~paride/curtin:20.1-29-g81144052-0ubuntu1 |
Merge into: | curtin:ubuntu/devel |
Diff against target: |
4246 lines (+1378/-939) 84 files modified
Makefile (+1/-1) curtin/__init__.py (+4/-0) curtin/block/__init__.py (+16/-1) curtin/block/dasd.py (+2/-2) curtin/block/multipath.py (+1/-1) curtin/commands/block_meta.py (+8/-3) curtin/commands/curthooks.py (+130/-16) curtin/commands/install_grub.py (+1/-1) curtin/commands/swap.py (+4/-1) curtin/distro.py (+23/-7) curtin/net/deps.py (+4/-1) curtin/swap.py (+79/-5) debian/changelog (+44/-0) dev/null (+0/-7) doc/topics/config.rst (+58/-1) examples/tests/basic.yaml (+4/-0) examples/tests/basic_scsi.yaml (+4/-0) examples/tests/network_v2_ovs.yaml (+3/-32) examples/tests/nvme_bcache.yaml (+2/-4) examples/tests/preserve-partition-wipe-vg.yaml (+0/-1) examples/tests/raid5boot.yaml (+1/-1) helpers/common (+0/-578) requirements.txt (+3/-0) tests/data/multipath-nvme.txt (+1/-0) tests/unittests/helpers.py (+18/-0) tests/unittests/test_block.py (+12/-0) tests/unittests/test_block_multipath.py (+14/-0) tests/unittests/test_commands_block_meta.py (+145/-5) tests/unittests/test_curthooks.py (+340/-52) tests/unittests/test_distro.py (+27/-6) tests/unittests/test_feature.py (+6/-0) tests/vmtests/__init__.py (+100/-22) tests/vmtests/releases.py (+9/-0) tests/vmtests/test_apt_config_cmd.py (+5/-1) tests/vmtests/test_basic.py (+23/-10) tests/vmtests/test_basic_dasd.py (+2/-2) tests/vmtests/test_bcache_basic.py (+2/-2) tests/vmtests/test_bcache_bug1718699.py (+2/-2) tests/vmtests/test_bcache_ceph.py (+6/-2) tests/vmtests/test_bcache_partitions.py (+2/-2) tests/vmtests/test_fs_battery.py (+2/-2) tests/vmtests/test_iscsi.py (+2/-2) tests/vmtests/test_journald_reporter.py (+2/-2) tests/vmtests/test_lvm.py (+2/-2) tests/vmtests/test_lvm_iscsi.py (+2/-2) tests/vmtests/test_lvm_raid.py (+4/-4) tests/vmtests/test_lvm_root.py (+17/-4) tests/vmtests/test_mdadm_bcache.py (+39/-30) tests/vmtests/test_mdadm_iscsi.py (+2/-2) tests/vmtests/test_multipath.py (+2/-2) tests/vmtests/test_multipath_lvm.py (+7/-2) tests/vmtests/test_network.py (+2/-2) tests/vmtests/test_network_alias.py (+2/-2) tests/vmtests/test_network_bonding.py (+2/-2) tests/vmtests/test_network_bridging.py (+2/-2) tests/vmtests/test_network_disabled.py (+17/-0) tests/vmtests/test_network_ipv6.py (+5/-1) tests/vmtests/test_network_ipv6_static.py (+2/-2) tests/vmtests/test_network_ipv6_vlan.py (+6/-6) tests/vmtests/test_network_mtu.py (+7/-15) tests/vmtests/test_network_ovs.py (+2/-3) tests/vmtests/test_network_static.py (+2/-2) tests/vmtests/test_network_static_routes.py (+4/-4) tests/vmtests/test_network_vlan.py (+3/-4) tests/vmtests/test_nvme.py (+3/-4) tests/vmtests/test_panic.py (+5/-0) tests/vmtests/test_pollinate_useragent.py (+2/-2) tests/vmtests/test_preserve.py (+2/-2) tests/vmtests/test_preserve_bcache.py (+2/-2) tests/vmtests/test_preserve_lvm.py (+2/-2) tests/vmtests/test_preserve_partition_wipe_vg.py (+5/-4) tests/vmtests/test_preserve_raid.py (+2/-2) tests/vmtests/test_raid5_bcache.py (+5/-5) tests/vmtests/test_reuse_lvm_member.py (+4/-4) tests/vmtests/test_reuse_msdos_partitions.py (+4/-4) tests/vmtests/test_reuse_raid_member.py (+6/-6) tests/vmtests/test_reuse_uefi_esp.py (+10/-10) tests/vmtests/test_simple.py (+11/-4) tests/vmtests/test_uefi_basic.py (+9/-4) tests/vmtests/test_zfsroot.py (+4/-5) tools/curtainer (+43/-7) tools/jenkins-runner (+14/-2) tools/run-pep8 (+1/-1) tools/vmtest-remove-release (+1/-1) |
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Server Team CI bot | continuous-integration | Approve | |
Ryan Harper (community) | Approve | ||
Review via email: mp+390692@code.launchpad.net |
Commit message
releasing curtin version 20.1-29-
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 : | # |
PASSED: Continuous integration, rev:602618759f4
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
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/Makefile b/Makefile | |||
2 | index 68a3ad3..187132c 100644 | |||
3 | --- a/Makefile | |||
4 | +++ b/Makefile | |||
5 | @@ -9,7 +9,7 @@ ifeq ($(COVERAGE), 1) | |||
6 | 9 | endif | 9 | endif |
7 | 10 | CURTIN_VMTEST_IMAGE_SYNC ?= False | 10 | CURTIN_VMTEST_IMAGE_SYNC ?= False |
8 | 11 | export CURTIN_VMTEST_IMAGE_SYNC | 11 | export CURTIN_VMTEST_IMAGE_SYNC |
10 | 12 | noseopts ?= -vv --nologcapture | 12 | noseopts ?= -vv |
11 | 13 | pylintopts ?= --rcfile=pylintrc --errors-only | 13 | pylintopts ?= --rcfile=pylintrc --errors-only |
12 | 14 | target_dirs ?= curtin tests tools | 14 | target_dirs ?= curtin tests tools |
13 | 15 | 15 | ||
14 | diff --git a/curtin/__init__.py b/curtin/__init__.py | |||
15 | index 2e1a0ed..092020b 100644 | |||
16 | --- a/curtin/__init__.py | |||
17 | +++ b/curtin/__init__.py | |||
18 | @@ -8,6 +8,8 @@ KERNEL_CMDLINE_COPY_TO_INSTALL_SEP = "---" | |||
19 | 8 | # can determine which features are supported. Each entry should have | 8 | # can determine which features are supported. Each entry should have |
20 | 9 | # a consistent meaning. | 9 | # a consistent meaning. |
21 | 10 | FEATURES = [ | 10 | FEATURES = [ |
22 | 11 | # curtin supports creating swapfiles on btrfs, if possible | ||
23 | 12 | 'BTRFS_SWAPFILE', | ||
24 | 11 | # curtin can apply centos networking via centos_apply_network_config | 13 | # curtin can apply centos networking via centos_apply_network_config |
25 | 12 | 'CENTOS_APPLY_NETWORK_CONFIG', | 14 | 'CENTOS_APPLY_NETWORK_CONFIG', |
26 | 13 | # curtin can configure centos storage devices and boot devices | 15 | # curtin can configure centos storage devices and boot devices |
27 | @@ -32,6 +34,8 @@ FEATURES = [ | |||
28 | 32 | 'APT_CONFIG_V1', | 34 | 'APT_CONFIG_V1', |
29 | 33 | # has version module | 35 | # has version module |
30 | 34 | 'HAS_VERSION_MODULE', | 36 | 'HAS_VERSION_MODULE', |
31 | 37 | # uefi_reoder has fallback support if BootCurrent is missing | ||
32 | 38 | 'UEFI_REORDER_FALLBACK_SUPPORT', | ||
33 | 35 | ] | 39 | ] |
34 | 36 | 40 | ||
35 | 37 | __version__ = "20.1" | 41 | __version__ = "20.1" |
36 | diff --git a/curtin/block/__init__.py b/curtin/block/__init__.py | |||
37 | index 35e3a64..10b8b9e 100644 | |||
38 | --- a/curtin/block/__init__.py | |||
39 | +++ b/curtin/block/__init__.py | |||
40 | @@ -1,5 +1,5 @@ | |||
41 | 1 | # This file is part of curtin. See LICENSE file for copyright and license info. | 1 | # This file is part of curtin. See LICENSE file for copyright and license info. |
43 | 2 | 2 | import re | |
44 | 3 | from contextlib import contextmanager | 3 | from contextlib import contextmanager |
45 | 4 | import errno | 4 | import errno |
46 | 5 | import itertools | 5 | import itertools |
47 | @@ -67,6 +67,19 @@ def dev_path(devname): | |||
48 | 67 | return '/dev/' + devname | 67 | return '/dev/' + devname |
49 | 68 | 68 | ||
50 | 69 | 69 | ||
51 | 70 | def md_path(mdname): | ||
52 | 71 | """ Convert device name to path in /dev/md """ | ||
53 | 72 | full_mdname = dev_path(mdname) | ||
54 | 73 | if full_mdname.startswith('/dev/md/'): | ||
55 | 74 | return full_mdname | ||
56 | 75 | elif re.match(r'/dev/md\d+$', full_mdname): | ||
57 | 76 | return full_mdname | ||
58 | 77 | elif '/' in mdname: | ||
59 | 78 | raise ValueError("Invalid RAID device name: {}".format(mdname)) | ||
60 | 79 | else: | ||
61 | 80 | return '/dev/md/{}'.format(mdname) | ||
62 | 81 | |||
63 | 82 | |||
64 | 70 | def path_to_kname(path): | 83 | def path_to_kname(path): |
65 | 71 | """ | 84 | """ |
66 | 72 | converts a path in /dev or a path in /sys/block to the device kname, | 85 | converts a path in /dev or a path in /sys/block to the device kname, |
67 | @@ -840,6 +853,8 @@ def _get_dev_disk_by_prefix(prefix): | |||
68 | 840 | '/dev/sda1': '/dev/disk/<prefix>/virtio-aaaa-part1', | 853 | '/dev/sda1': '/dev/disk/<prefix>/virtio-aaaa-part1', |
69 | 841 | } | 854 | } |
70 | 842 | """ | 855 | """ |
71 | 856 | if not os.path.exists(prefix): | ||
72 | 857 | return {} | ||
73 | 843 | return { | 858 | return { |
74 | 844 | os.path.realpath(bypfx): bypfx | 859 | os.path.realpath(bypfx): bypfx |
75 | 845 | for bypfx in [os.path.join(prefix, path) | 860 | for bypfx in [os.path.join(prefix, path) |
76 | diff --git a/curtin/block/dasd.py b/curtin/block/dasd.py | |||
77 | index 682f9d3..b7008f6 100644 | |||
78 | --- a/curtin/block/dasd.py | |||
79 | +++ b/curtin/block/dasd.py | |||
80 | @@ -269,9 +269,9 @@ def _valid_device_id(device_id): | |||
81 | 269 | if not (0 <= int(dsn, 16) < 256): | 269 | if not (0 <= int(dsn, 16) < 256): |
82 | 270 | raise ValueError("device_id invalid: dsn not in 0-255: '%s'" % dsn) | 270 | raise ValueError("device_id invalid: dsn not in 0-255: '%s'" % dsn) |
83 | 271 | 271 | ||
85 | 272 | if not (0 <= int(dev.lower(), 16) < 65535): | 272 | if not (0 <= int(dev.lower(), 16) <= 65535): |
86 | 273 | raise ValueError( | 273 | raise ValueError( |
88 | 274 | "device_id invalid: devno not in 0-0x10000: '%s'" % dev) | 274 | "device_id invalid: devno not in 0-0xffff: '%s'" % dev) |
89 | 275 | 275 | ||
90 | 276 | return True | 276 | return True |
91 | 277 | 277 | ||
92 | diff --git a/curtin/block/multipath.py b/curtin/block/multipath.py | |||
93 | index 9c7f510..7ad1791 100644 | |||
94 | --- a/curtin/block/multipath.py | |||
95 | +++ b/curtin/block/multipath.py | |||
96 | @@ -7,7 +7,7 @@ from curtin import udev | |||
97 | 7 | SHOW_PATHS_FMT = ("device='%d' serial='%z' multipath='%m' host_wwpn='%N' " | 7 | SHOW_PATHS_FMT = ("device='%d' serial='%z' multipath='%m' host_wwpn='%N' " |
98 | 8 | "target_wwnn='%n' host_wwpn='%R' target_wwpn='%r' " | 8 | "target_wwnn='%n' host_wwpn='%R' target_wwpn='%r' " |
99 | 9 | "host_adapter='%a'") | 9 | "host_adapter='%a'") |
101 | 10 | SHOW_MAPS_FMT = "name=%n multipath='%w' sysfs='%d' paths='%N'" | 10 | SHOW_MAPS_FMT = "name='%n' multipath='%w' sysfs='%d' paths='%N'" |
102 | 11 | 11 | ||
103 | 12 | 12 | ||
104 | 13 | def _extract_mpath_data(cmd, show_verb): | 13 | def _extract_mpath_data(cmd, show_verb): |
105 | diff --git a/curtin/commands/block_meta.py b/curtin/commands/block_meta.py | |||
106 | index ff0f2e9..dee73b1 100644 | |||
107 | --- a/curtin/commands/block_meta.py | |||
108 | +++ b/curtin/commands/block_meta.py | |||
109 | @@ -502,7 +502,7 @@ def get_path_to_storage_volume(volume, storage_config): | |||
110 | 502 | elif vol.get('type') == "raid": | 502 | elif vol.get('type') == "raid": |
111 | 503 | # For raid partitions, block device is at /dev/mdX | 503 | # For raid partitions, block device is at /dev/mdX |
112 | 504 | name = vol.get('name') | 504 | name = vol.get('name') |
114 | 505 | volume_path = os.path.join("/dev", name) | 505 | volume_path = block.md_path(name) |
115 | 506 | 506 | ||
116 | 507 | elif vol.get('type') == "bcache": | 507 | elif vol.get('type') == "bcache": |
117 | 508 | # For bcache setups, the only reliable way to determine the name of the | 508 | # For bcache setups, the only reliable way to determine the name of the |
118 | @@ -1485,7 +1485,7 @@ def raid_handler(info, storage_config): | |||
119 | 1485 | devices = info.get('devices') | 1485 | devices = info.get('devices') |
120 | 1486 | raidlevel = info.get('raidlevel') | 1486 | raidlevel = info.get('raidlevel') |
121 | 1487 | spare_devices = info.get('spare_devices') | 1487 | spare_devices = info.get('spare_devices') |
123 | 1488 | md_devname = block.dev_path(info.get('name')) | 1488 | md_devname = block.md_path(info.get('name')) |
124 | 1489 | preserve = config.value_as_boolean(info.get('preserve')) | 1489 | preserve = config.value_as_boolean(info.get('preserve')) |
125 | 1490 | if not devices: | 1490 | if not devices: |
126 | 1491 | raise ValueError("devices for raid must be specified") | 1491 | raise ValueError("devices for raid must be specified") |
127 | @@ -1744,7 +1744,12 @@ def get_device_paths_from_storage_config(storage_config): | |||
128 | 1744 | dpaths = [] | 1744 | dpaths = [] |
129 | 1745 | for (k, v) in storage_config.items(): | 1745 | for (k, v) in storage_config.items(): |
130 | 1746 | if v.get('type') in ['disk', 'partition']: | 1746 | if v.get('type') in ['disk', 'partition']: |
132 | 1747 | if config.value_as_boolean(v.get('wipe')): | 1747 | wipe = config.value_as_boolean(v.get('wipe')) |
133 | 1748 | preserve = config.value_as_boolean(v.get('preserve')) | ||
134 | 1749 | if v.get('type') == 'disk' and all([wipe, preserve]): | ||
135 | 1750 | msg = 'type:disk id=%s has both wipe and preserve' % v['id'] | ||
136 | 1751 | raise RuntimeError(msg) | ||
137 | 1752 | if wipe: | ||
138 | 1748 | try: | 1753 | try: |
139 | 1749 | # skip paths that do not exit, nothing to wipe | 1754 | # skip paths that do not exit, nothing to wipe |
140 | 1750 | dpath = get_path_to_storage_volume(k, storage_config) | 1755 | dpath = get_path_to_storage_volume(k, storage_config) |
141 | diff --git a/curtin/commands/curthooks.py b/curtin/commands/curthooks.py | |||
142 | index d66afa7..4cf7301 100644 | |||
143 | --- a/curtin/commands/curthooks.py | |||
144 | +++ b/curtin/commands/curthooks.py | |||
145 | @@ -85,6 +85,8 @@ do_initrd = yes | |||
146 | 85 | link_in_boot = {inboot} | 85 | link_in_boot = {inboot} |
147 | 86 | """ | 86 | """ |
148 | 87 | 87 | ||
149 | 88 | UEFI_BOOT_ENTRY_IS_NETWORK = r'.*(Network|PXE|NIC|Ethernet|LAN|IP4|IP6)+.*' | ||
150 | 89 | |||
151 | 88 | 90 | ||
152 | 89 | def do_apt_config(cfg, target): | 91 | def do_apt_config(cfg, target): |
153 | 90 | cfg = apt_config.translate_old_apt_features(cfg) | 92 | cfg = apt_config.translate_old_apt_features(cfg) |
154 | @@ -411,6 +413,7 @@ def install_kernel(cfg, target): | |||
155 | 411 | def uefi_remove_old_loaders(grubcfg, target): | 413 | def uefi_remove_old_loaders(grubcfg, target): |
156 | 412 | """Removes the old UEFI loaders from efibootmgr.""" | 414 | """Removes the old UEFI loaders from efibootmgr.""" |
157 | 413 | efi_output = util.get_efibootmgr(target) | 415 | efi_output = util.get_efibootmgr(target) |
158 | 416 | LOG.debug('UEFI remove old olders efi output:\n%s', efi_output) | ||
159 | 414 | current_uefi_boot = efi_output.get('current', None) | 417 | current_uefi_boot = efi_output.get('current', None) |
160 | 415 | old_efi_entries = { | 418 | old_efi_entries = { |
161 | 416 | entry: info | 419 | entry: info |
162 | @@ -437,18 +440,90 @@ def uefi_remove_old_loaders(grubcfg, target): | |||
163 | 437 | "should be removed.", info['name']) | 440 | "should be removed.", info['name']) |
164 | 438 | 441 | ||
165 | 439 | 442 | ||
167 | 440 | def uefi_reorder_loaders(grubcfg, target): | 443 | def uefi_boot_entry_is_network(boot_entry_name): |
168 | 444 | """ | ||
169 | 445 | Return boolean if boot entry name looks like a known network entry. | ||
170 | 446 | """ | ||
171 | 447 | return re.match(UEFI_BOOT_ENTRY_IS_NETWORK, | ||
172 | 448 | boot_entry_name, re.IGNORECASE) is not None | ||
173 | 449 | |||
174 | 450 | |||
175 | 451 | def _reorder_new_entry(boot_order, efi_output, efi_orig=None, variant=None): | ||
176 | 452 | """ | ||
177 | 453 | Reorder the EFI boot menu as follows | ||
178 | 454 | |||
179 | 455 | 1. All PXE/Network boot entries | ||
180 | 456 | 2. The newly installed entry variant (ubuntu/centos) | ||
181 | 457 | 3. The other items in the boot order that are not in [1, 2] | ||
182 | 458 | |||
183 | 459 | returns a list of bootnum strings | ||
184 | 460 | """ | ||
185 | 461 | |||
186 | 462 | if not boot_order: | ||
187 | 463 | raise RuntimeError('boot_order is not a list') | ||
188 | 464 | |||
189 | 465 | if efi_orig is None: | ||
190 | 466 | raise RuntimeError('Missing efi_orig boot dictionary') | ||
191 | 467 | |||
192 | 468 | if variant is None: | ||
193 | 469 | variant = "" | ||
194 | 470 | |||
195 | 471 | net_boot = [] | ||
196 | 472 | other = [] | ||
197 | 473 | target = [] | ||
198 | 474 | |||
199 | 475 | LOG.debug("UEFI previous boot order: %s", efi_orig['order']) | ||
200 | 476 | LOG.debug("UEFI current boot order: %s", boot_order) | ||
201 | 477 | new_entries = list(set(boot_order).difference(set(efi_orig['order']))) | ||
202 | 478 | if new_entries: | ||
203 | 479 | LOG.debug("UEFI Found new boot entries: %s", new_entries) | ||
204 | 480 | LOG.debug('UEFI Looking for installed entry variant=%s', variant.lower()) | ||
205 | 481 | for bootnum in boot_order: | ||
206 | 482 | entry = efi_output['entries'][bootnum] | ||
207 | 483 | if uefi_boot_entry_is_network(entry['name']): | ||
208 | 484 | net_boot.append(bootnum) | ||
209 | 485 | else: | ||
210 | 486 | if entry['name'].lower() == variant.lower(): | ||
211 | 487 | target.append(bootnum) | ||
212 | 488 | else: | ||
213 | 489 | other.append(bootnum) | ||
214 | 490 | |||
215 | 491 | if net_boot: | ||
216 | 492 | LOG.debug("UEFI found netboot entries: %s", net_boot) | ||
217 | 493 | if other: | ||
218 | 494 | LOG.debug("UEFI found other entries: %s", other) | ||
219 | 495 | if target: | ||
220 | 496 | LOG.debug("UEFI found target entry: %s", target) | ||
221 | 497 | else: | ||
222 | 498 | LOG.debug("UEFI Did not find an entry with variant=%s", | ||
223 | 499 | variant.lower()) | ||
224 | 500 | new_order = net_boot + target + other | ||
225 | 501 | if boot_order == new_order: | ||
226 | 502 | LOG.debug("UEFI Current and Previous bootorders match") | ||
227 | 503 | return new_order | ||
228 | 504 | |||
229 | 505 | |||
230 | 506 | def uefi_reorder_loaders(grubcfg, target, efi_orig=None, variant=None): | ||
231 | 441 | """Reorders the UEFI BootOrder to place BootCurrent first. | 507 | """Reorders the UEFI BootOrder to place BootCurrent first. |
232 | 442 | 508 | ||
233 | 443 | The specifically doesn't try to do to much. The order in which grub places | 509 | The specifically doesn't try to do to much. The order in which grub places |
234 | 444 | a new EFI loader is up to grub. This only moves the BootCurrent to the | 510 | a new EFI loader is up to grub. This only moves the BootCurrent to the |
235 | 445 | front of the BootOrder. | 511 | front of the BootOrder. |
236 | 512 | |||
237 | 513 | In some systems, BootCurrent may not be set/present. In this case | ||
238 | 514 | curtin will attempt to place the new boot entry created when grub | ||
239 | 515 | is installed after the the previous first entry (before we installed grub). | ||
240 | 516 | |||
241 | 446 | """ | 517 | """ |
242 | 447 | if grubcfg.get('reorder_uefi', True): | 518 | if grubcfg.get('reorder_uefi', True): |
243 | 448 | efi_output = util.get_efibootmgr(target=target) | 519 | efi_output = util.get_efibootmgr(target=target) |
244 | 520 | LOG.debug('UEFI efibootmgr output after install:\n%s', efi_output) | ||
245 | 449 | currently_booted = efi_output.get('current', None) | 521 | currently_booted = efi_output.get('current', None) |
246 | 450 | boot_order = efi_output.get('order', []) | 522 | boot_order = efi_output.get('order', []) |
248 | 451 | if currently_booted: | 523 | new_boot_order = None |
249 | 524 | force_fallback_reorder = config.value_as_boolean( | ||
250 | 525 | grubcfg.get('reorder_uefi_force_fallback', False)) | ||
251 | 526 | if currently_booted and force_fallback_reorder is False: | ||
252 | 452 | if currently_booted in boot_order: | 527 | if currently_booted in boot_order: |
253 | 453 | boot_order.remove(currently_booted) | 528 | boot_order.remove(currently_booted) |
254 | 454 | boot_order = [currently_booted] + boot_order | 529 | boot_order = [currently_booted] + boot_order |
255 | @@ -456,6 +531,23 @@ def uefi_reorder_loaders(grubcfg, target): | |||
256 | 456 | LOG.debug( | 531 | LOG.debug( |
257 | 457 | "Setting currently booted %s as the first " | 532 | "Setting currently booted %s as the first " |
258 | 458 | "UEFI loader.", currently_booted) | 533 | "UEFI loader.", currently_booted) |
259 | 534 | else: | ||
260 | 535 | reason = ( | ||
261 | 536 | "config 'reorder_uefi_force_fallback' is True" if | ||
262 | 537 | force_fallback_reorder else "missing 'BootCurrent' value") | ||
263 | 538 | LOG.debug("Using fallback UEFI reordering: " + reason) | ||
264 | 539 | if len(boot_order) < 2: | ||
265 | 540 | LOG.debug( | ||
266 | 541 | 'UEFI BootOrder has less than 2 entries, cannot reorder') | ||
267 | 542 | return | ||
268 | 543 | # look at efi entries before we added one to find the new addition | ||
269 | 544 | new_order = _reorder_new_entry( | ||
270 | 545 | copy.deepcopy(boot_order), efi_output, efi_orig, variant) | ||
271 | 546 | if new_order != boot_order: | ||
272 | 547 | new_boot_order = ','.join(new_order) | ||
273 | 548 | else: | ||
274 | 549 | LOG.debug("UEFI No changes to boot order.") | ||
275 | 550 | if new_boot_order: | ||
276 | 459 | LOG.debug( | 551 | LOG.debug( |
277 | 460 | "New UEFI boot order: %s", new_boot_order) | 552 | "New UEFI boot order: %s", new_boot_order) |
278 | 461 | with util.ChrootableTarget(target) as in_chroot: | 553 | with util.ChrootableTarget(target) as in_chroot: |
279 | @@ -465,25 +557,44 @@ def uefi_reorder_loaders(grubcfg, target): | |||
280 | 465 | LOG.debug("Currently booted UEFI loader might no longer boot.") | 557 | LOG.debug("Currently booted UEFI loader might no longer boot.") |
281 | 466 | 558 | ||
282 | 467 | 559 | ||
284 | 468 | def uefi_remove_duplicate_entries(grubcfg, target): | 560 | def uefi_remove_duplicate_entries(grubcfg, target, to_remove=None): |
285 | 561 | if not grubcfg.get('remove_duplicate_entries', True): | ||
286 | 562 | LOG.debug("Skipped removing duplicate UEFI boot entries per config.") | ||
287 | 563 | return | ||
288 | 564 | if to_remove is None: | ||
289 | 565 | to_remove = uefi_find_duplicate_entries(grubcfg, target) | ||
290 | 566 | |||
291 | 567 | # check so we don't run ChrootableTarget code unless we have things to do | ||
292 | 568 | if to_remove: | ||
293 | 569 | with util.ChrootableTarget(target) as in_chroot: | ||
294 | 570 | for bootnum, entry in to_remove: | ||
295 | 571 | LOG.debug('Removing duplicate EFI entry (%s, %s)', | ||
296 | 572 | bootnum, entry) | ||
297 | 573 | in_chroot.subp(['efibootmgr', '--bootnum=%s' % bootnum, | ||
298 | 574 | '--delete-bootnum']) | ||
299 | 575 | |||
300 | 576 | |||
301 | 577 | def uefi_find_duplicate_entries(grubcfg, target, efi_output=None): | ||
302 | 469 | seen = set() | 578 | seen = set() |
303 | 470 | to_remove = [] | 579 | to_remove = [] |
305 | 471 | efi_output = util.get_efibootmgr(target=target) | 580 | if efi_output is None: |
306 | 581 | efi_output = util.get_efibootmgr(target=target) | ||
307 | 472 | entries = efi_output.get('entries', {}) | 582 | entries = efi_output.get('entries', {}) |
308 | 583 | current_bootnum = efi_output.get('current', None) | ||
309 | 584 | # adding BootCurrent to seen first allows us to remove any other duplicate | ||
310 | 585 | # entry of BootCurrent. | ||
311 | 586 | if current_bootnum: | ||
312 | 587 | seen.add(tuple(entries[current_bootnum].items())) | ||
313 | 473 | for bootnum in sorted(entries): | 588 | for bootnum in sorted(entries): |
314 | 589 | if bootnum == current_bootnum: | ||
315 | 590 | continue | ||
316 | 474 | entry = entries[bootnum] | 591 | entry = entries[bootnum] |
317 | 475 | t = tuple(entry.items()) | 592 | t = tuple(entry.items()) |
318 | 476 | if t not in seen: | 593 | if t not in seen: |
319 | 477 | seen.add(t) | 594 | seen.add(t) |
320 | 478 | else: | 595 | else: |
321 | 479 | to_remove.append((bootnum, entry)) | 596 | to_remove.append((bootnum, entry)) |
329 | 480 | if to_remove: | 597 | return to_remove |
323 | 481 | with util.ChrootableTarget(target) as in_chroot: | ||
324 | 482 | for bootnum, entry in to_remove: | ||
325 | 483 | LOG.debug('Removing duplicate EFI entry (%s, %s)', | ||
326 | 484 | bootnum, entry) | ||
327 | 485 | in_chroot.subp(['efibootmgr', '--bootnum=%s' % bootnum, | ||
328 | 486 | '--delete-bootnum']) | ||
330 | 487 | 598 | ||
331 | 488 | 599 | ||
332 | 489 | def _debconf_multiselect(package, variable, choices): | 600 | def _debconf_multiselect(package, variable, choices): |
333 | @@ -557,7 +668,7 @@ def uefi_find_grub_device_ids(sconfig): | |||
334 | 557 | esp_partitions.append(item_id) | 668 | esp_partitions.append(item_id) |
335 | 558 | continue | 669 | continue |
336 | 559 | 670 | ||
338 | 560 | if item['type'] == 'mount' and item['path'] == '/boot/efi': | 671 | if item['type'] == 'mount' and item.get('path') == '/boot/efi': |
339 | 561 | if primary_esp: | 672 | if primary_esp: |
340 | 562 | LOG.debug('Ignoring duplicate mounted primary ESP: %s', | 673 | LOG.debug('Ignoring duplicate mounted primary ESP: %s', |
341 | 563 | item_id) | 674 | item_id) |
342 | @@ -592,7 +703,7 @@ def uefi_find_grub_device_ids(sconfig): | |||
343 | 592 | return grub_device_ids | 703 | return grub_device_ids |
344 | 593 | 704 | ||
345 | 594 | 705 | ||
347 | 595 | def setup_grub(cfg, target, osfamily=DISTROS.debian): | 706 | def setup_grub(cfg, target, osfamily=DISTROS.debian, variant=None): |
348 | 596 | # target is the path to the mounted filesystem | 707 | # target is the path to the mounted filesystem |
349 | 597 | 708 | ||
350 | 598 | # FIXME: these methods need moving to curtin.block | 709 | # FIXME: these methods need moving to curtin.block |
351 | @@ -692,13 +803,14 @@ def setup_grub(cfg, target, osfamily=DISTROS.debian): | |||
352 | 692 | 803 | ||
353 | 693 | update_nvram = grubcfg.get('update_nvram', True) | 804 | update_nvram = grubcfg.get('update_nvram', True) |
354 | 694 | if uefi_bootable and update_nvram: | 805 | if uefi_bootable and update_nvram: |
355 | 806 | efi_orig_output = util.get_efibootmgr(target) | ||
356 | 695 | uefi_remove_old_loaders(grubcfg, target) | 807 | uefi_remove_old_loaders(grubcfg, target) |
357 | 696 | 808 | ||
358 | 697 | install_grub(instdevs, target, uefi=uefi_bootable, grubcfg=grubcfg) | 809 | install_grub(instdevs, target, uefi=uefi_bootable, grubcfg=grubcfg) |
359 | 698 | 810 | ||
360 | 699 | if uefi_bootable and update_nvram: | 811 | if uefi_bootable and update_nvram: |
361 | 812 | uefi_reorder_loaders(grubcfg, target, efi_orig_output, variant) | ||
362 | 700 | uefi_remove_duplicate_entries(grubcfg, target) | 813 | uefi_remove_duplicate_entries(grubcfg, target) |
363 | 701 | uefi_reorder_loaders(grubcfg, target) | ||
364 | 702 | 814 | ||
365 | 703 | 815 | ||
366 | 704 | def update_initramfs(target=None, all_kernels=False): | 816 | def update_initramfs(target=None, all_kernels=False): |
367 | @@ -900,6 +1012,7 @@ def add_swap(cfg, target, fstab): | |||
368 | 900 | fname = swapcfg.get('filename', None) | 1012 | fname = swapcfg.get('filename', None) |
369 | 901 | size = swapcfg.get('size', None) | 1013 | size = swapcfg.get('size', None) |
370 | 902 | maxsize = swapcfg.get('maxsize', None) | 1014 | maxsize = swapcfg.get('maxsize', None) |
371 | 1015 | force = swapcfg.get('force', False) | ||
372 | 903 | 1016 | ||
373 | 904 | if size: | 1017 | if size: |
374 | 905 | size = util.human2bytes(str(size)) | 1018 | size = util.human2bytes(str(size)) |
375 | @@ -907,7 +1020,7 @@ def add_swap(cfg, target, fstab): | |||
376 | 907 | maxsize = util.human2bytes(str(maxsize)) | 1020 | maxsize = util.human2bytes(str(maxsize)) |
377 | 908 | 1021 | ||
378 | 909 | swap.setup_swapfile(target=target, fstab=fstab, swapfile=fname, size=size, | 1022 | swap.setup_swapfile(target=target, fstab=fstab, swapfile=fname, size=size, |
380 | 910 | maxsize=maxsize) | 1023 | maxsize=maxsize, force=force) |
381 | 911 | 1024 | ||
382 | 912 | 1025 | ||
383 | 913 | def detect_and_handle_multipath(cfg, target, osfamily=DISTROS.debian): | 1026 | def detect_and_handle_multipath(cfg, target, osfamily=DISTROS.debian): |
384 | @@ -1733,7 +1846,8 @@ def builtin_curthooks(cfg, target, state): | |||
385 | 1733 | name=stack_prefix + '/install-grub', | 1846 | name=stack_prefix + '/install-grub', |
386 | 1734 | reporting_enabled=True, level="INFO", | 1847 | reporting_enabled=True, level="INFO", |
387 | 1735 | description="installing grub to target devices"): | 1848 | description="installing grub to target devices"): |
389 | 1736 | setup_grub(cfg, target, osfamily=osfamily) | 1849 | setup_grub(cfg, target, osfamily=osfamily, |
390 | 1850 | variant=distro_info.variant) | ||
391 | 1737 | 1851 | ||
392 | 1738 | 1852 | ||
393 | 1739 | def curthooks(args): | 1853 | def curthooks(args): |
394 | diff --git a/curtin/commands/install_grub.py b/curtin/commands/install_grub.py | |||
395 | index 777aa35..5f8311f 100644 | |||
396 | --- a/curtin/commands/install_grub.py | |||
397 | +++ b/curtin/commands/install_grub.py | |||
398 | @@ -346,7 +346,7 @@ def install_grub(devices, target, uefi=None, grubcfg=None): | |||
399 | 346 | 346 | ||
400 | 347 | LOG.debug("installing grub to target=%s devices=%s [replace_defaults=%s]", | 347 | LOG.debug("installing grub to target=%s devices=%s [replace_defaults=%s]", |
401 | 348 | target, devices, grubcfg.get('replace_default')) | 348 | target, devices, grubcfg.get('replace_default')) |
403 | 349 | update_nvram = config.value_as_boolean(grubcfg.get('update_nvram', False)) | 349 | update_nvram = config.value_as_boolean(grubcfg.get('update_nvram', True)) |
404 | 350 | distroinfo = distro.get_distroinfo(target=target) | 350 | distroinfo = distro.get_distroinfo(target=target) |
405 | 351 | target_arch = distro.get_architecture(target=target) | 351 | target_arch = distro.get_architecture(target=target) |
406 | 352 | rhel_ver = (distro.rpm_get_dist_id(target) | 352 | rhel_ver = (distro.rpm_get_dist_id(target) |
407 | diff --git a/curtin/commands/swap.py b/curtin/commands/swap.py | |||
408 | index f2381e6..089cd73 100644 | |||
409 | --- a/curtin/commands/swap.py | |||
410 | +++ b/curtin/commands/swap.py | |||
411 | @@ -40,7 +40,7 @@ def swap_main(args): | |||
412 | 40 | 40 | ||
413 | 41 | swap.setup_swapfile(target=state['target'], fstab=state['fstab'], | 41 | swap.setup_swapfile(target=state['target'], fstab=state['fstab'], |
414 | 42 | swapfile=args.swapfile, size=size, | 42 | swapfile=args.swapfile, size=size, |
416 | 43 | maxsize=args.maxsize) | 43 | maxsize=args.maxsize, force=args.force) |
417 | 44 | sys.exit(2) | 44 | sys.exit(2) |
418 | 45 | 45 | ||
419 | 46 | 46 | ||
420 | @@ -54,6 +54,9 @@ CMD_ARGUMENTS = ( | |||
421 | 54 | 'default is env[TARGET_MOUNT_POINT]'), | 54 | 'default is env[TARGET_MOUNT_POINT]'), |
422 | 55 | 'action': 'store', 'metavar': 'TARGET', | 55 | 'action': 'store', 'metavar': 'TARGET', |
423 | 56 | 'default': os.environ.get('TARGET_MOUNT_POINT')}), | 56 | 'default': os.environ.get('TARGET_MOUNT_POINT')}), |
424 | 57 | (('-F', '--force'), | ||
425 | 58 | {'help': 'force creating of swapfile even if it may fail (btrfs,xfs)', | ||
426 | 59 | 'default': False, 'action': 'store_true'}), | ||
427 | 57 | (('-s', '--size'), | 60 | (('-s', '--size'), |
428 | 58 | {'help': 'size of swap file (eg: 1G, 1500M, 1024K, 100000. def: "auto")', | 61 | {'help': 'size of swap file (eg: 1G, 1500M, 1024K, 100000. def: "auto")', |
429 | 59 | 'default': None, 'action': 'store'}), | 62 | 'default': None, 'action': 'store'}), |
430 | diff --git a/curtin/distro.py b/curtin/distro.py | |||
431 | index 43b0c19..82a4dd5 100644 | |||
432 | --- a/curtin/distro.py | |||
433 | +++ b/curtin/distro.py | |||
434 | @@ -264,7 +264,7 @@ def apt_update(target=None, env=None, force=False, comment=None, | |||
435 | 264 | 264 | ||
436 | 265 | 265 | ||
437 | 266 | def run_apt_command(mode, args=None, opts=None, env=None, target=None, | 266 | def run_apt_command(mode, args=None, opts=None, env=None, target=None, |
439 | 267 | execute=True, allow_daemons=False): | 267 | execute=True, allow_daemons=False, clean=True): |
440 | 268 | defopts = ['--quiet', '--assume-yes', | 268 | defopts = ['--quiet', '--assume-yes', |
441 | 269 | '--option=Dpkg::options::=--force-unsafe-io', | 269 | '--option=Dpkg::options::=--force-unsafe-io', |
442 | 270 | '--option=Dpkg::Options::=--force-confold'] | 270 | '--option=Dpkg::Options::=--force-confold'] |
443 | @@ -289,7 +289,11 @@ def run_apt_command(mode, args=None, opts=None, env=None, target=None, | |||
444 | 289 | 289 | ||
445 | 290 | apt_update(target, env=env, comment=' '.join(cmd)) | 290 | apt_update(target, env=env, comment=' '.join(cmd)) |
446 | 291 | with ChrootableTarget(target, allow_daemons=allow_daemons) as inchroot: | 291 | with ChrootableTarget(target, allow_daemons=allow_daemons) as inchroot: |
448 | 292 | return inchroot.subp(cmd, env=env) | 292 | cmd_rv = inchroot.subp(cmd, env=env) |
449 | 293 | if clean and mode in ['dist-upgrade', 'install', 'upgrade']: | ||
450 | 294 | inchroot.subp(['apt-get', 'clean']) | ||
451 | 295 | |||
452 | 296 | return cmd_rv | ||
453 | 293 | 297 | ||
454 | 294 | 298 | ||
455 | 295 | def run_yum_command(mode, args=None, opts=None, env=None, target=None, | 299 | def run_yum_command(mode, args=None, opts=None, env=None, target=None, |
456 | @@ -472,6 +476,7 @@ def parse_dpkg_version(raw, name=None, semx=None): | |||
457 | 472 | as the upstream version. | 476 | as the upstream version. |
458 | 473 | 477 | ||
459 | 474 | returns a dictionary with fields: | 478 | returns a dictionary with fields: |
460 | 479 | 'epoch' | ||
461 | 475 | 'major' (int), 'minor' (int), 'micro' (int), | 480 | 'major' (int), 'minor' (int), 'micro' (int), |
462 | 476 | 'semantic_version' (int), | 481 | 'semantic_version' (int), |
463 | 477 | 'extra' (string), 'raw' (string), 'upstream' (string), | 482 | 'extra' (string), 'raw' (string), 'upstream' (string), |
464 | @@ -484,12 +489,20 @@ def parse_dpkg_version(raw, name=None, semx=None): | |||
465 | 484 | if semx is None: | 489 | if semx is None: |
466 | 485 | semx = (10000, 100, 1) | 490 | semx = (10000, 100, 1) |
467 | 486 | 491 | ||
470 | 487 | if "-" in raw: | 492 | raw_offset = 0 |
471 | 488 | upstream = raw.rsplit('-', 1)[0] | 493 | if ':' in raw: |
472 | 494 | epoch, _, upstream = raw.partition(':') | ||
473 | 495 | raw_offset = len(epoch) + 1 | ||
474 | 489 | else: | 496 | else: |
476 | 490 | # this is a native package, package version treated as upstream. | 497 | epoch = 0 |
477 | 491 | upstream = raw | 498 | upstream = raw |
478 | 492 | 499 | ||
479 | 500 | if "-" in raw[raw_offset:]: | ||
480 | 501 | upstream = raw[raw_offset:].rsplit('-', 1)[0] | ||
481 | 502 | else: | ||
482 | 503 | # this is a native package, package version treated as upstream. | ||
483 | 504 | upstream = raw[raw_offset:] | ||
484 | 505 | |||
485 | 493 | match = re.search(r'[^0-9.]', upstream) | 506 | match = re.search(r'[^0-9.]', upstream) |
486 | 494 | if match: | 507 | if match: |
487 | 495 | extra = upstream[match.start():] | 508 | extra = upstream[match.start():] |
488 | @@ -498,8 +511,10 @@ def parse_dpkg_version(raw, name=None, semx=None): | |||
489 | 498 | upstream_base = upstream | 511 | upstream_base = upstream |
490 | 499 | extra = None | 512 | extra = None |
491 | 500 | 513 | ||
494 | 501 | toks = upstream_base.split(".", 2) | 514 | toks = upstream_base.split(".", 3) |
495 | 502 | if len(toks) == 3: | 515 | if len(toks) == 4: |
496 | 516 | major, minor, micro, extra = toks | ||
497 | 517 | elif len(toks) == 3: | ||
498 | 503 | major, minor, micro = toks | 518 | major, minor, micro = toks |
499 | 504 | elif len(toks) == 2: | 519 | elif len(toks) == 2: |
500 | 505 | major, minor, micro = (toks[0], toks[1], 0) | 520 | major, minor, micro = (toks[0], toks[1], 0) |
501 | @@ -507,6 +522,7 @@ def parse_dpkg_version(raw, name=None, semx=None): | |||
502 | 507 | major, minor, micro = (toks[0], 0, 0) | 522 | major, minor, micro = (toks[0], 0, 0) |
503 | 508 | 523 | ||
504 | 509 | version = { | 524 | version = { |
505 | 525 | 'epoch': int(epoch), | ||
506 | 510 | 'major': int(major), | 526 | 'major': int(major), |
507 | 511 | 'minor': int(minor), | 527 | 'minor': int(minor), |
508 | 512 | 'micro': int(micro), | 528 | 'micro': int(micro), |
509 | diff --git a/curtin/net/deps.py b/curtin/net/deps.py | |||
510 | index f912d1d..b78654d 100644 | |||
511 | --- a/curtin/net/deps.py | |||
512 | +++ b/curtin/net/deps.py | |||
513 | @@ -34,10 +34,13 @@ def network_config_required_packages(network_config, mapping=None): | |||
514 | 34 | if cfgtype == 'version': | 34 | if cfgtype == 'version': |
515 | 35 | continue | 35 | continue |
516 | 36 | dev_configs.add(cfgtype) | 36 | dev_configs.add(cfgtype) |
518 | 37 | # the renderer type may trigger package adds | 37 | # subkeys under the type may trigger package adds |
519 | 38 | for entry, entry_cfg in cfg.items(): | 38 | for entry, entry_cfg in cfg.items(): |
520 | 39 | if entry_cfg.get('renderer'): | 39 | if entry_cfg.get('renderer'): |
521 | 40 | dev_configs.add(entry_cfg.get('renderer')) | 40 | dev_configs.add(entry_cfg.get('renderer')) |
522 | 41 | else: | ||
523 | 42 | for sub_entry, sub_cfg in entry_cfg.items(): | ||
524 | 43 | dev_configs.add(sub_entry) | ||
525 | 41 | 44 | ||
526 | 42 | needed_packages = [] | 45 | needed_packages = [] |
527 | 43 | for dev_type in dev_configs: | 46 | for dev_type in dev_configs: |
528 | diff --git a/curtin/swap.py b/curtin/swap.py | |||
529 | index d3f29dc..11e95c4 100644 | |||
530 | --- a/curtin/swap.py | |||
531 | +++ b/curtin/swap.py | |||
532 | @@ -5,6 +5,8 @@ import resource | |||
533 | 5 | 5 | ||
534 | 6 | from .log import LOG | 6 | from .log import LOG |
535 | 7 | from . import util | 7 | from . import util |
536 | 8 | from curtin import paths | ||
537 | 9 | from curtin import distro | ||
538 | 8 | 10 | ||
539 | 9 | 11 | ||
540 | 10 | def suggested_swapsize(memsize=None, maxsize=None, fsys=None): | 12 | def suggested_swapsize(memsize=None, maxsize=None, fsys=None): |
541 | @@ -51,7 +53,62 @@ def suggested_swapsize(memsize=None, maxsize=None, fsys=None): | |||
542 | 51 | return maxsize | 53 | return maxsize |
543 | 52 | 54 | ||
544 | 53 | 55 | ||
546 | 54 | def setup_swapfile(target, fstab=None, swapfile=None, size=None, maxsize=None): | 56 | def get_fstype(target, source): |
547 | 57 | target_source = paths.target_path(target, source) | ||
548 | 58 | try: | ||
549 | 59 | out, _ = util.subp(['findmnt', '--noheading', '--target', | ||
550 | 60 | target_source, '-o', 'FSTYPE'], capture=True) | ||
551 | 61 | except util.ProcessExecutionError as exc: | ||
552 | 62 | LOG.warning('Failed to query %s fstype, findmnt returned error: %s', | ||
553 | 63 | target_source, exc) | ||
554 | 64 | return None | ||
555 | 65 | |||
556 | 66 | if out: | ||
557 | 67 | """ | ||
558 | 68 | $ findmnt --noheading --target /btrfs -o FSTYPE | ||
559 | 69 | btrfs | ||
560 | 70 | """ | ||
561 | 71 | return out.splitlines()[-1] | ||
562 | 72 | |||
563 | 73 | return None | ||
564 | 74 | |||
565 | 75 | |||
566 | 76 | def get_target_kernel_version(target): | ||
567 | 77 | pkg_ver = None | ||
568 | 78 | |||
569 | 79 | distro_info = distro.get_distroinfo(target=target) | ||
570 | 80 | if not distro_info: | ||
571 | 81 | raise RuntimeError('Failed to determine target distro') | ||
572 | 82 | osfamily = distro_info.family | ||
573 | 83 | if osfamily == distro.DISTROS.debian: | ||
574 | 84 | try: | ||
575 | 85 | # check in-target version | ||
576 | 86 | pkg_ver = distro.get_package_version('linux-image-generic', | ||
577 | 87 | target=target) | ||
578 | 88 | except Exception as e: | ||
579 | 89 | LOG.warn( | ||
580 | 90 | "failed reading linux-image-generic package version, %s", e) | ||
581 | 91 | return pkg_ver | ||
582 | 92 | |||
583 | 93 | |||
584 | 94 | def can_use_swapfile(target, fstype): | ||
585 | 95 | if fstype is None: | ||
586 | 96 | raise RuntimeError( | ||
587 | 97 | 'Unknown target filesystem type, may not support swapfiles') | ||
588 | 98 | if fstype in ['btrfs', 'xfs']: | ||
589 | 99 | # check kernel version | ||
590 | 100 | pkg_ver = get_target_kernel_version(target) | ||
591 | 101 | if not pkg_ver: | ||
592 | 102 | raise RuntimeError('Failed to read target kernel version') | ||
593 | 103 | if fstype == 'btrfs' and pkg_ver['major'] < 5: | ||
594 | 104 | raise RuntimeError( | ||
595 | 105 | 'btrfs requiers kernel version 5.0+ to use swapfiles') | ||
596 | 106 | elif fstype in ['zfs']: | ||
597 | 107 | raise RuntimeError('ZFS cannot use swapfiles') | ||
598 | 108 | |||
599 | 109 | |||
600 | 110 | def setup_swapfile(target, fstab=None, swapfile=None, size=None, maxsize=None, | ||
601 | 111 | force=False): | ||
602 | 55 | if size is None: | 112 | if size is None: |
603 | 56 | size = suggested_swapsize(fsys=target, maxsize=maxsize) | 113 | size = suggested_swapsize(fsys=target, maxsize=maxsize) |
604 | 57 | 114 | ||
605 | @@ -65,6 +122,24 @@ def setup_swapfile(target, fstab=None, swapfile=None, size=None, maxsize=None): | |||
606 | 65 | if not swapfile.startswith("/"): | 122 | if not swapfile.startswith("/"): |
607 | 66 | swapfile = "/" + swapfile | 123 | swapfile = "/" + swapfile |
608 | 67 | 124 | ||
609 | 125 | # query the directory in which swapfile will reside | ||
610 | 126 | fstype = get_fstype(target, os.path.dirname(swapfile)) | ||
611 | 127 | try: | ||
612 | 128 | can_use_swapfile(target, fstype) | ||
613 | 129 | except RuntimeError as err: | ||
614 | 130 | if force: | ||
615 | 131 | LOG.warning('swapfile may not work: %s', err) | ||
616 | 132 | else: | ||
617 | 133 | LOG.debug('Not creating swap: %s', err) | ||
618 | 134 | return | ||
619 | 135 | |||
620 | 136 | allocate_cmd = 'fallocate -l "${2}M" "$1"' | ||
621 | 137 | # fallocate uses IOCTLs to allocate space in a filesystem, however it's not | ||
622 | 138 | # clear (from curtin's POV) that it creates non-sparse files as required by | ||
623 | 139 | # mkswap so we'll skip fallocate for now and use dd. | ||
624 | 140 | if fstype in ['btrfs', 'xfs']: | ||
625 | 141 | allocate_cmd = 'dd if=/dev/zero "of=$1" bs=1M "count=$2"' | ||
626 | 142 | |||
627 | 68 | mbsize = str(int(size / (2 ** 20))) | 143 | mbsize = str(int(size / (2 ** 20))) |
628 | 69 | msg = "creating swap file '%s' of %sMB" % (swapfile, mbsize) | 144 | msg = "creating swap file '%s' of %sMB" % (swapfile, mbsize) |
629 | 70 | fpath = os.path.sep.join([target, swapfile]) | 145 | fpath = os.path.sep.join([target, swapfile]) |
630 | @@ -73,10 +148,9 @@ def setup_swapfile(target, fstab=None, swapfile=None, size=None, maxsize=None): | |||
631 | 73 | with util.LogTimer(LOG.debug, msg): | 148 | with util.LogTimer(LOG.debug, msg): |
632 | 74 | util.subp( | 149 | util.subp( |
633 | 75 | ['sh', '-c', | 150 | ['sh', '-c', |
638 | 76 | ('rm -f "$1" && umask 0066 && ' | 151 | ('rm -f "$1" && umask 0066 && truncate -s 0 "$1" && ' |
639 | 77 | '{ fallocate -l "${2}M" "$1" || ' | 152 | '{ chattr +C "$1" || true; } && ') + allocate_cmd + |
640 | 78 | ' dd if=/dev/zero "of=$1" bs=1M "count=$2"; } && ' | 153 | (' && mkswap "$1" || { r=$?; rm -f "$1"; exit $r; }'), |
637 | 79 | 'mkswap "$1" || { r=$?; rm -f "$1"; exit $r; }'), | ||
641 | 80 | 'setup_swap', fpath, mbsize]) | 154 | 'setup_swap', fpath, mbsize]) |
642 | 81 | except Exception: | 155 | except Exception: |
643 | 82 | LOG.warn("failed %s" % msg) | 156 | LOG.warn("failed %s" % msg) |
644 | diff --git a/debian/changelog b/debian/changelog | |||
645 | index e1a75e1..265d939 100644 | |||
646 | --- a/debian/changelog | |||
647 | +++ b/debian/changelog | |||
648 | @@ -1,3 +1,47 @@ | |||
649 | 1 | curtin (20.1-29-g81144052-0ubuntu1) groovy; urgency=medium | ||
650 | 2 | |||
651 | 3 | * New upstream snapshot. | ||
652 | 4 | - vmtest: Fix multiple issues with vmtest on master | ||
653 | 5 | - Refactor uefi_remove_duplicates into find/remove functions for reuse | ||
654 | 6 | - distro: run apt-get clean after dist-upgrade, install, upgrade | ||
655 | 7 | - curthooks: UEFI remove dupes: don't remove BootCurrent, config option | ||
656 | 8 | (LP: #1894217) | ||
657 | 9 | - Pin the dependency on pyrsistent [Paride Legovini] | ||
658 | 10 | - restore default of grub.update_nvram to True in install_grub | ||
659 | 11 | [Michael Hudson-Doyle] | ||
660 | 12 | - block: disk_to_byid_path handle missing /dev/disk/by-id directory | ||
661 | 13 | (LP: #1876258) | ||
662 | 14 | - UEFI: Handle missing BootCurrent entry when reordering UEFI entries | ||
663 | 15 | (LP: #1789650) | ||
664 | 16 | - dasd: fix off-by-one device_id devno range check [Paride Legovini] | ||
665 | 17 | - curthooks: uefi_find_grub_device_ids handle type:mount without path | ||
666 | 18 | (LP: #1892242) | ||
667 | 19 | - netplan openvswitch yaml changed (LP: #1891608) | ||
668 | 20 | - tools/curtainer: do not wait for snapd.seeded.service | ||
669 | 21 | - tools/curtainer: enable using ubuntu-minimal images | ||
670 | 22 | - vmtests: add Groovy [Paride Legovini] | ||
671 | 23 | - Drop the Eoan vmtests (EOL) [Paride Legovini] | ||
672 | 24 | - tools: rename remove-vmtest-release to vmtest-remove-release | ||
673 | 25 | - Snooze the tests failing because of LP: #1861941 for two more months | ||
674 | 26 | [Paride Legovini] | ||
675 | 27 | - LP: #1671951 is Fix Released => Drop the PPA [Paride Legovini] | ||
676 | 28 | - swaps: handle swapfiles on btrfs (LP: #1884161) | ||
677 | 29 | - curtainer: fail is masking of zfs-mount or zfs-share fails | ||
678 | 30 | [Paride Legovini] | ||
679 | 31 | - multipath: handle multipath nvme name fields correctly (LP: #1878041) | ||
680 | 32 | - curtainer: mask the zfs-mount and zfs-share services [Paride Legovini] | ||
681 | 33 | - tools/jenkins-runner: shuffle test-cases to randomize load | ||
682 | 34 | [Paride Legovini] | ||
683 | 35 | - Add Trusty/UEFI/HWE-X vmtest, drop realpath add, drop shell code | ||
684 | 36 | - LP: #1881977 - Install realpath on Trusty UEFI. [Lee Trager] | ||
685 | 37 | - vmtests: fix PreservePartitionWipeVg storage config | ||
686 | 38 | - Fix mdraid name creates broken configuration | ||
687 | 39 | [James Falcon] (LP: #1803933) | ||
688 | 40 | - vmtests: update skiptests | ||
689 | 41 | - vmtest: allow installed centos images to reboot (LP: #1881011) | ||
690 | 42 | |||
691 | 43 | -- Paride Legovini <paride.legovini@canonical.com> Mon, 14 Sep 2020 17:53:15 +0200 | ||
692 | 44 | |||
693 | 1 | curtin (20.1-0ubuntu1) groovy; urgency=medium | 45 | curtin (20.1-0ubuntu1) groovy; urgency=medium |
694 | 2 | 46 | ||
695 | 3 | * New upstream release. | 47 | * New upstream release. |
696 | diff --git a/doc/topics/config.rst b/doc/topics/config.rst | |||
697 | index 72cd683..ec8a109 100644 | |||
698 | --- a/doc/topics/config.rst | |||
699 | +++ b/doc/topics/config.rst | |||
700 | @@ -226,6 +226,42 @@ not provided, Curtin will set the value to 'console'. If the ``terminal`` | |||
701 | 226 | value is 'unmodified' then Curtin will not set any value at all and will | 226 | value is 'unmodified' then Curtin will not set any value at all and will |
702 | 227 | use Grub defaults. | 227 | use Grub defaults. |
703 | 228 | 228 | ||
704 | 229 | **reorder_uefi**: *<boolean: default True>* | ||
705 | 230 | |||
706 | 231 | Curtin is typically used with MAAS where the systems are configured to boot | ||
707 | 232 | from the network leaving MAAS in control. On UEFI systems, after installing | ||
708 | 233 | a bootloader the systems BootOrder may be updated to boot from the new entry. | ||
709 | 234 | This breaks MAAS control over the system as all subsequent reboots of the node | ||
710 | 235 | will no longer boot over the network. Therefore, if ``reorder_uefi`` is True | ||
711 | 236 | curtin will modify the UEFI BootOrder settings to place the currently booted | ||
712 | 237 | entry (BootCurrent) to the first option after installing the new target OS into | ||
713 | 238 | the UEFI boot menu. The result is that the system will boot from the same | ||
714 | 239 | device that it booted to run curtin; for MAAS this will be a network device. | ||
715 | 240 | |||
716 | 241 | On some UEFI systems the BootCurrent entry may not be present. This can | ||
717 | 242 | cause a system to not boot to the same device that it was previously booting. | ||
718 | 243 | If BootCurrent is not present, curtin will update the BootOrder such that | ||
719 | 244 | all Network related entries are placed before the newly installed boot entry and | ||
720 | 245 | all other entries are placed at the end. This enables the system to network | ||
721 | 246 | boot first and on failure will boot the most recently installed entry. | ||
722 | 247 | |||
723 | 248 | This setting is ignored if *update_nvram* is False. | ||
724 | 249 | |||
725 | 250 | **reorder_uefi_force_fallback**: *<boolean: default False>* | ||
726 | 251 | |||
727 | 252 | The fallback reodering mechanism is only active if BootCurrent is not present | ||
728 | 253 | in the efibootmgr output. The fallback reordering method may be enabled | ||
729 | 254 | even if BootCurrent is present if *reorder_uefi_force_fallback* is True. | ||
730 | 255 | |||
731 | 256 | This setting is ignored if *update_nvram* or *reorder_uefi* are False. | ||
732 | 257 | |||
733 | 258 | **remove_duplicate_entries**: <*boolean: default True>* | ||
734 | 259 | |||
735 | 260 | When curtin updates UEFI NVRAM it will remove duplicate entries that are | ||
736 | 261 | present in the UEFI menu. If you do not wish for curtin to remove duplicate | ||
737 | 262 | entries setting *remove_duplicate_entries* to False. | ||
738 | 263 | |||
739 | 264 | This setting is ignored if *update_nvram* is False. | ||
740 | 229 | 265 | ||
741 | 230 | **Example**:: | 266 | **Example**:: |
742 | 231 | 267 | ||
743 | @@ -235,6 +271,7 @@ use Grub defaults. | |||
744 | 235 | replace_linux_default: False | 271 | replace_linux_default: False |
745 | 236 | update_nvram: True | 272 | update_nvram: True |
746 | 237 | terminal: serial | 273 | terminal: serial |
747 | 274 | remove_duplicate_entries: True | ||
748 | 238 | 275 | ||
749 | 239 | **Default terminal value, GRUB_TERMINAL=console**:: | 276 | **Default terminal value, GRUB_TERMINAL=console**:: |
750 | 240 | 277 | ||
751 | @@ -264,6 +301,12 @@ use Grub defaults. | |||
752 | 264 | probe_additional_os: True | 301 | probe_additional_os: True |
753 | 265 | terminal: unmodified | 302 | terminal: unmodified |
754 | 266 | 303 | ||
755 | 304 | **Enable Fallback UEFI Reordering**:: | ||
756 | 305 | |||
757 | 306 | grub: | ||
758 | 307 | reorder_uefi: true | ||
759 | 308 | reorder_uefi_force_fallback: true | ||
760 | 309 | |||
761 | 267 | 310 | ||
762 | 268 | http_proxy | 311 | http_proxy |
763 | 269 | ~~~~~~~~~~ | 312 | ~~~~~~~~~~ |
764 | @@ -752,13 +795,27 @@ Configure the max size of the swapfile, defaults to 8GB | |||
765 | 752 | Configure the exact size of the swapfile. Setting ``size`` to 0 will | 795 | Configure the exact size of the swapfile. Setting ``size`` to 0 will |
766 | 753 | disable swap. | 796 | disable swap. |
767 | 754 | 797 | ||
768 | 798 | **force**: *<boolean>* | ||
769 | 799 | |||
770 | 800 | Force the creation of swapfile even if curtin detects it may not work. | ||
771 | 801 | In some target filesystems, e.g. btrfs, xfs, zfs, the use of a swap file has | ||
772 | 802 | restrictions. If curtin detects that there may be issues it will refuse | ||
773 | 803 | to create the swapfile. Users can force creation of a swapfile by passing | ||
774 | 804 | ``force: true``. A forced swapfile may not be used by the target OS and could | ||
775 | 805 | log cause an error. | ||
776 | 806 | |||
777 | 755 | **Example**:: | 807 | **Example**:: |
778 | 756 | 808 | ||
779 | 757 | swap: | 809 | swap: |
780 | 758 | filename: swap.img | 810 | filename: swap.img |
782 | 759 | size: None | 811 | size: 1GB |
783 | 760 | maxsize: 4GB | 812 | maxsize: 4GB |
784 | 761 | 813 | ||
785 | 814 | swap: | ||
786 | 815 | filename: btrfs_swapfile.img | ||
787 | 816 | size: 1GB | ||
788 | 817 | force: true | ||
789 | 818 | |||
790 | 762 | 819 | ||
791 | 763 | system_upgrade | 820 | system_upgrade |
792 | 764 | ~~~~~~~~~~~~~~ | 821 | ~~~~~~~~~~~~~~ |
793 | diff --git a/examples/tests/basic.yaml b/examples/tests/basic.yaml | |||
794 | index 71730c0..82f5ad1 100644 | |||
795 | --- a/examples/tests/basic.yaml | |||
796 | +++ b/examples/tests/basic.yaml | |||
797 | @@ -1,4 +1,8 @@ | |||
798 | 1 | showtrace: true | 1 | showtrace: true |
799 | 2 | swap: | ||
800 | 3 | filename: /btrfs/btrfsswap.img | ||
801 | 4 | size: 1GB | ||
802 | 5 | maxsize: 1GB | ||
803 | 2 | storage: | 6 | storage: |
804 | 3 | version: 1 | 7 | version: 1 |
805 | 4 | config: | 8 | config: |
806 | diff --git a/examples/tests/basic_scsi.yaml b/examples/tests/basic_scsi.yaml | |||
807 | index 51f5236..fd28bbe 100644 | |||
808 | --- a/examples/tests/basic_scsi.yaml | |||
809 | +++ b/examples/tests/basic_scsi.yaml | |||
810 | @@ -1,4 +1,8 @@ | |||
811 | 1 | showtrace: true | 1 | showtrace: true |
812 | 2 | swap: | ||
813 | 3 | filename: /btrfs/btrfsswap.img | ||
814 | 4 | size: 1GB | ||
815 | 5 | maxsize: 1GB | ||
816 | 2 | storage: | 6 | storage: |
817 | 3 | version: 1 | 7 | version: 1 |
818 | 4 | config: | 8 | config: |
819 | diff --git a/examples/tests/network_v2_ovs.yaml b/examples/tests/network_v2_ovs.yaml | |||
820 | index 6d1dc3d..0d063ce 100644 | |||
821 | --- a/examples/tests/network_v2_ovs.yaml | |||
822 | +++ b/examples/tests/network_v2_ovs.yaml | |||
823 | @@ -8,35 +8,6 @@ network: | |||
824 | 8 | match: | 8 | match: |
825 | 9 | macaddress: '52:54:00:12:34:00' | 9 | macaddress: '52:54:00:12:34:00' |
826 | 10 | set-name: eth0 | 10 | set-name: eth0 |
859 | 11 | eth1: | 11 | bridges: |
860 | 12 | match: | 12 | br-empty: |
861 | 13 | macaddress: '52:54:00:12:34:02' | 13 | openvswitch: {} |
830 | 14 | set-name: eth1 | ||
831 | 15 | eth2: | ||
832 | 16 | match: | ||
833 | 17 | macaddress: '52:54:00:12:34:04' | ||
834 | 18 | set-name: eth2 | ||
835 | 19 | openvswitch: | ||
836 | 20 | bridges: | ||
837 | 21 | br-int: | ||
838 | 22 | fail-mode: secure | ||
839 | 23 | datapath_type: system | ||
840 | 24 | stp: false | ||
841 | 25 | rstp: false | ||
842 | 26 | mcast-snooping: false | ||
843 | 27 | controller: | ||
844 | 28 | addresses: | ||
845 | 29 | - tcp:127.0.0.1:6653 | ||
846 | 30 | protocols: | ||
847 | 31 | - OpenFlow10 | ||
848 | 32 | - OpenFlow12 | ||
849 | 33 | - OpenFlow13 | ||
850 | 34 | ports: | ||
851 | 35 | patch-tun: | ||
852 | 36 | type: patch | ||
853 | 37 | options: | ||
854 | 38 | peer: patch-int | ||
855 | 39 | eth1: | ||
856 | 40 | tag: 2 | ||
857 | 41 | eth2: | ||
858 | 42 | tag: 2 | ||
862 | diff --git a/examples/tests/nvme_bcache.yaml b/examples/tests/nvme_bcache.yaml | |||
863 | index 4fefd94..ed705c4 100644 | |||
864 | --- a/examples/tests/nvme_bcache.yaml | |||
865 | +++ b/examples/tests/nvme_bcache.yaml | |||
866 | @@ -1,8 +1,7 @@ | |||
867 | 1 | showtrace: true | 1 | showtrace: true |
868 | 2 | storage: | 2 | storage: |
869 | 3 | config: | 3 | config: |
872 | 4 | - grub_device: true | 4 | - id: sda |
871 | 5 | id: sda | ||
873 | 6 | model: LOGICAL VOLUME | 5 | model: LOGICAL VOLUME |
874 | 7 | name: sda | 6 | name: sda |
875 | 8 | ptable: gpt | 7 | ptable: gpt |
876 | @@ -23,7 +22,7 @@ storage: | |||
877 | 23 | type: disk | 22 | type: disk |
878 | 24 | wipe: superblock | 23 | wipe: superblock |
879 | 25 | - device: sda | 24 | - device: sda |
881 | 26 | flag: boot | 25 | grub_device: true |
882 | 27 | id: sda-part1 | 26 | id: sda-part1 |
883 | 28 | name: sda-part1 | 27 | name: sda-part1 |
884 | 29 | number: 1 | 28 | number: 1 |
885 | @@ -33,7 +32,6 @@ storage: | |||
886 | 33 | uuid: 9f0fda16-c096-4cee-82ac-4f5f294253a2 | 32 | uuid: 9f0fda16-c096-4cee-82ac-4f5f294253a2 |
887 | 34 | wipe: superblock | 33 | wipe: superblock |
888 | 35 | - device: sda | 34 | - device: sda |
889 | 36 | flag: boot | ||
890 | 37 | id: sda-part2 | 35 | id: sda-part2 |
891 | 38 | name: sda-part2 | 36 | name: sda-part2 |
892 | 39 | number: 2 | 37 | number: 2 |
893 | diff --git a/examples/tests/preserve-partition-wipe-vg.yaml b/examples/tests/preserve-partition-wipe-vg.yaml | |||
894 | index 97686e1..27a4235 100644 | |||
895 | --- a/examples/tests/preserve-partition-wipe-vg.yaml | |||
896 | +++ b/examples/tests/preserve-partition-wipe-vg.yaml | |||
897 | @@ -38,7 +38,6 @@ storage: | |||
898 | 38 | grub_device: true | 38 | grub_device: true |
899 | 39 | type: disk | 39 | type: disk |
900 | 40 | id: disk-sda | 40 | id: disk-sda |
901 | 41 | wipe: superblock | ||
902 | 42 | - serial: disk-b | 41 | - serial: disk-b |
903 | 43 | name: disk-b | 42 | name: disk-b |
904 | 44 | grub_device: false | 43 | grub_device: false |
905 | diff --git a/examples/tests/raid5boot.yaml b/examples/tests/raid5boot.yaml | |||
906 | index b1df21d..d8afe7f 100644 | |||
907 | --- a/examples/tests/raid5boot.yaml | |||
908 | +++ b/examples/tests/raid5boot.yaml | |||
909 | @@ -42,7 +42,7 @@ storage: | |||
910 | 42 | size: 3GB | 42 | size: 3GB |
911 | 43 | device: sdc | 43 | device: sdc |
912 | 44 | - id: mddevice | 44 | - id: mddevice |
914 | 45 | name: md0 | 45 | name: os-raid1 |
915 | 46 | type: raid | 46 | type: raid |
916 | 47 | raidlevel: 5 | 47 | raidlevel: 5 |
917 | 48 | devices: | 48 | devices: |
918 | diff --git a/helpers/common b/helpers/common | |||
919 | index 5638d39..4afb6a1 100644 | |||
920 | --- a/helpers/common | |||
921 | +++ b/helpers/common | |||
922 | @@ -29,19 +29,6 @@ EOF | |||
923 | 29 | [ $# -eq 0 ] || echo "$@" | 29 | [ $# -eq 0 ] || echo "$@" |
924 | 30 | } | 30 | } |
925 | 31 | 31 | ||
926 | 32 | grub_install_usage() { | ||
927 | 33 | cat <<EOF | ||
928 | 34 | Usage: ${0##*/} [ options ] mount-point target-dev | ||
929 | 35 | |||
930 | 36 | perform grub-install with mount-point onto target-dev. | ||
931 | 37 | |||
932 | 38 | options: | ||
933 | 39 | --uefi install grub-efi instead of grub-pc | ||
934 | 40 | --update-nvram request grub to update nvram | ||
935 | 41 | EOF | ||
936 | 42 | [ $# -eq 0 ] || echo "$@" | ||
937 | 43 | } | ||
938 | 44 | |||
939 | 45 | cleanup() { | 32 | cleanup() { |
940 | 46 | if [ -d "$TEMP_D" ]; then | 33 | if [ -d "$TEMP_D" ]; then |
941 | 47 | rm -Rf "$TEMP_D" | 34 | rm -Rf "$TEMP_D" |
942 | @@ -480,569 +467,4 @@ getsize() { | |||
943 | 480 | fi | 467 | fi |
944 | 481 | } | 468 | } |
945 | 482 | 469 | ||
946 | 483 | is_md() { | ||
947 | 484 | case "${1##*/}" in | ||
948 | 485 | md[0-9]) return 0;; | ||
949 | 486 | esac | ||
950 | 487 | return 1 | ||
951 | 488 | } | ||
952 | 489 | |||
953 | 490 | get_carryover_params() { | ||
954 | 491 | local cmdline=" $1 " extra="" lead="" carry_extra="" carry_lead="" | ||
955 | 492 | # return a string to append to installed systems boot parameters | ||
956 | 493 | # it may include a '--' after a '---' | ||
957 | 494 | # see LP: 1402042 for some history here. | ||
958 | 495 | # this is similar to 'user-params' from d-i | ||
959 | 496 | local preferred_sep="---" # KERNEL_CMDLINE_COPY_TO_INSTALL_SEP | ||
960 | 497 | local legacy_sep="--" | ||
961 | 498 | case "$cmdline" in | ||
962 | 499 | *\ ${preferred_sep}\ *) | ||
963 | 500 | extra=${cmdline#* ${preferred_sep} } | ||
964 | 501 | lead=${cmdline%% ${preferred_sep} *} | ||
965 | 502 | ;; | ||
966 | 503 | *\ ${legacy_sep}\ *) | ||
967 | 504 | extra="${cmdline#* ${legacy_sep} }" | ||
968 | 505 | lead=${cmdline%% ${legacy_sep} *} | ||
969 | 506 | ;; | ||
970 | 507 | *) | ||
971 | 508 | extra="" | ||
972 | 509 | lead="$cmdline" | ||
973 | 510 | ;; | ||
974 | 511 | esac | ||
975 | 512 | |||
976 | 513 | if [ -n "$extra" ]; then | ||
977 | 514 | carry_extra=$(set -f; | ||
978 | 515 | c=""; | ||
979 | 516 | for p in $extra; do | ||
980 | 517 | case "$p" in | ||
981 | 518 | (BOOTIF=*|initrd=*|BOOT_IMAGE=*) continue;; | ||
982 | 519 | esac | ||
983 | 520 | c="$c $p"; | ||
984 | 521 | done | ||
985 | 522 | echo "${c# }" | ||
986 | 523 | ) | ||
987 | 524 | fi | ||
988 | 525 | |||
989 | 526 | # these get copied even if they werent after the separator | ||
990 | 527 | local padded=" $carry_extra " | ||
991 | 528 | carry_lead=$(set -f; | ||
992 | 529 | padded=" ${carry_extra} " | ||
993 | 530 | c="" | ||
994 | 531 | for p in $lead; do | ||
995 | 532 | # skip any that are already in carry_extra | ||
996 | 533 | [ "${padded#* $p }" != "$padded" ] && continue | ||
997 | 534 | case "$p" in | ||
998 | 535 | (console=*) c="$c $p";; | ||
999 | 536 | esac | ||
1000 | 537 | done | ||
1001 | 538 | echo "${c# }" | ||
1002 | 539 | ) | ||
1003 | 540 | [ -n "${carry_lead}" -a -n "${carry_extra}" ] && | ||
1004 | 541 | carry_lead="${carry_lead} " | ||
1005 | 542 | _RET="${carry_lead}${carry_extra}" | ||
1006 | 543 | } | ||
1007 | 544 | |||
1008 | 545 | shell_config_update() { | ||
1009 | 546 | # shell_config_update(file, name, value) | ||
1010 | 547 | # update variable 'name' setting value to 'val' in shell syntax 'file'. | ||
1011 | 548 | # if 'name' is not present, then append declaration. | ||
1012 | 549 | local file="$1" name="$2" val="$3" | ||
1013 | 550 | if ! [ -f "$file" ] || ! grep -q "^$name=" "$file"; then | ||
1014 | 551 | debug 2 "appending to $file shell $name=\"$val\"" | ||
1015 | 552 | echo "$name=\"$val\"" >> "$file" | ||
1016 | 553 | return | ||
1017 | 554 | fi | ||
1018 | 555 | local cand="" del="" | ||
1019 | 556 | for cand in "|" "," "/"; do | ||
1020 | 557 | [ "${val#*${del}}" = "${val}" ] && del="$cand" && break | ||
1021 | 558 | done | ||
1022 | 559 | [ -n "$del" ] || { | ||
1023 | 560 | error "Couldn't find a sed delimiter for '$val'"; | ||
1024 | 561 | return 1; | ||
1025 | 562 | } | ||
1026 | 563 | |||
1027 | 564 | sed -i -e "s${del}^$name=.*${del}$name=\"$val\"${del}" "$file" || | ||
1028 | 565 | { error "Failed editing '$file' to set $name=$val"; return 1; } | ||
1029 | 566 | debug 2 "updated $file to set $name=\"$val\"" | ||
1030 | 567 | return 0 | ||
1031 | 568 | } | ||
1032 | 569 | |||
1033 | 570 | apply_grub_cmdline_linux_default() { | ||
1034 | 571 | local mp="$1" newargs="$2" edg="${3:-etc/default/grub}" | ||
1035 | 572 | local gcld="GRUB_CMDLINE_LINUX_DEFAULT" | ||
1036 | 573 | debug 1 "setting $gcld to '$newargs' in $edg" | ||
1037 | 574 | shell_config_update "$mp/$edg" "$gcld" "$newargs" || { | ||
1038 | 575 | error "Failed to set '$gcld=$newargs' in $edg" | ||
1039 | 576 | return 1 | ||
1040 | 577 | } | ||
1041 | 578 | } | ||
1042 | 579 | |||
1043 | 580 | get_parent_disk() { | ||
1044 | 581 | # Look up the parent /dev path via sysfs. Using the partition | ||
1045 | 582 | # kname (nvme0n1p1), construct a /sys/class/block path, use | ||
1046 | 583 | # realpath to resolve this to an absolute path which includes | ||
1047 | 584 | # the parent: | ||
1048 | 585 | # /sys/devices/pci0000:00/*/*/nvme/nvme0/nvme0n1/nvme0n1p1 | ||
1049 | 586 | # dirname to extract the parent, then read the 'dev' entry | ||
1050 | 587 | # /sys/devices/pci0000:00/*/*/nvme/nvme0/nvme0n1/dev | ||
1051 | 588 | # which contains the MAJOR:MINOR value and construct a /dev/block | ||
1052 | 589 | # path which is a symbolic link that udev constructs that points | ||
1053 | 590 | # to the real device name and use realpath to return the absolute path. | ||
1054 | 591 | # /dev/block/259:0 -> ../nvme0n1 | ||
1055 | 592 | local devpath="${1}" | ||
1056 | 593 | local kname=$(basename "$devpath") | ||
1057 | 594 | local syspath=$(realpath "/sys/class/block/$kname") | ||
1058 | 595 | local disksyspath=$(dirname "$syspath") | ||
1059 | 596 | local diskmajmin=$(cat "${disksyspath}/dev") | ||
1060 | 597 | local diskdevpath=$(realpath "/dev/block/${diskmajmin}") | ||
1061 | 598 | echo $diskdevpath | ||
1062 | 599 | } | ||
1063 | 600 | |||
1064 | 601 | install_grub() { | ||
1065 | 602 | local long_opts="uefi,update-nvram,os-family:" | ||
1066 | 603 | local getopt_out="" mp_efi="" | ||
1067 | 604 | getopt_out=$(getopt --name "${0##*/}" \ | ||
1068 | 605 | --options "" --long "${long_opts}" -- "$@") && | ||
1069 | 606 | eval set -- "${getopt_out}" | ||
1070 | 607 | |||
1071 | 608 | local uefi=0 update_nvram=0 os_family="" | ||
1072 | 609 | |||
1073 | 610 | while [ $# -ne 0 ]; do | ||
1074 | 611 | cur="$1"; next="$2"; | ||
1075 | 612 | case "$cur" in | ||
1076 | 613 | --os-family) os_family=${next};; | ||
1077 | 614 | --uefi) uefi=$((${uefi}+1));; | ||
1078 | 615 | --update-nvram) update_nvram=$((${update_nvram}+1));; | ||
1079 | 616 | --) shift; break;; | ||
1080 | 617 | esac | ||
1081 | 618 | shift; | ||
1082 | 619 | done | ||
1083 | 620 | |||
1084 | 621 | [ $# -lt 2 ] && { grub_install_usage "must provide mount-point and target-dev" 1>&2; return 1; } | ||
1085 | 622 | |||
1086 | 623 | local mp="$1" | ||
1087 | 624 | local cmdline tmp r="" | ||
1088 | 625 | shift | ||
1089 | 626 | local grubdevs | ||
1090 | 627 | grubdevs=( "$@" ) | ||
1091 | 628 | if [ "${#grubdevs[@]}" = "1" -a "${grubdevs[0]}" = "none" ]; then | ||
1092 | 629 | grubdevs=( ) | ||
1093 | 630 | fi | ||
1094 | 631 | debug 1 "grubdevs: [${grubdevs[@]}]" | ||
1095 | 632 | |||
1096 | 633 | # find the mp device | ||
1097 | 634 | local mp_dev="" fstype="" | ||
1098 | 635 | mp_dev=$(awk -v "MP=$mp" '$2 == MP { print $1 }' /proc/mounts) || { | ||
1099 | 636 | error "unable to determine device for mount $mp"; | ||
1100 | 637 | return 1; | ||
1101 | 638 | } | ||
1102 | 639 | debug 1 "/proc/mounts shows $mp_dev is mounted at $mp" | ||
1103 | 640 | |||
1104 | 641 | fstype=$(awk -v MP=$mp '$2 == MP { print $3 }' /proc/mounts) || { | ||
1105 | 642 | error "unable to fstype for mount $mp"; | ||
1106 | 643 | return 1; | ||
1107 | 644 | } | ||
1108 | 645 | |||
1109 | 646 | [ -z "$mp_dev" ] && { | ||
1110 | 647 | error "did not find '$mp' in /proc/mounts" | ||
1111 | 648 | cat /proc/mounts 1>&2 | ||
1112 | 649 | return 1 | ||
1113 | 650 | } | ||
1114 | 651 | # check if parsed mount point is a block device | ||
1115 | 652 | # error unless fstype is zfs, where entry will not point to block device. | ||
1116 | 653 | if ! [ -b "$mp_dev" ] && [ "$fstype" != "zfs" ]; then | ||
1117 | 654 | # error unless mp is zfs, entry doesn't point to block devs | ||
1118 | 655 | error "$mp_dev ($fstype) is not a block device!"; return 1; | ||
1119 | 656 | fi | ||
1120 | 657 | |||
1121 | 658 | local os_variant="" | ||
1122 | 659 | if [ -e "${mp}/etc/os-release" ]; then | ||
1123 | 660 | os_variant=$(chroot "$mp" \ | ||
1124 | 661 | /bin/sh -c 'echo $(. /etc/os-release; echo $ID)') | ||
1125 | 662 | else | ||
1126 | 663 | # Centos6 doesn't have os-release, so check for centos/redhat release | ||
1127 | 664 | # looks like: CentOS release 6.9 (Final) | ||
1128 | 665 | for rel in $(ls ${mp}/etc/*-release); do | ||
1129 | 666 | os_variant=$(awk '{print tolower($1)}' $rel) | ||
1130 | 667 | [ -n "$os_variant" ] && break | ||
1131 | 668 | done | ||
1132 | 669 | fi | ||
1133 | 670 | [ $? != 0 ] && | ||
1134 | 671 | { error "Failed to read ID from $mp/etc/os-release"; return 1; } | ||
1135 | 672 | |||
1136 | 673 | local rhel_ver="" | ||
1137 | 674 | case $os_variant in | ||
1138 | 675 | debian|ubuntu) os_family="debian";; | ||
1139 | 676 | centos|rhel) | ||
1140 | 677 | os_family="redhat" | ||
1141 | 678 | rhel_ver=$(chroot "$mp" rpm -E '%rhel') | ||
1142 | 679 | ;; | ||
1143 | 680 | esac | ||
1144 | 681 | |||
1145 | 682 | # ensure we have both settings, family and variant are needed | ||
1146 | 683 | [ -n "${os_variant}" -a -n "${os_family}" ] || | ||
1147 | 684 | { error "Failed to determine os variant and family"; return 1; } | ||
1148 | 685 | |||
1149 | 686 | # get target arch | ||
1150 | 687 | local target_arch="" r="1" | ||
1151 | 688 | case $os_family in | ||
1152 | 689 | debian) | ||
1153 | 690 | target_arch=$(chroot "$mp" dpkg --print-architecture) | ||
1154 | 691 | r=$? | ||
1155 | 692 | ;; | ||
1156 | 693 | redhat) | ||
1157 | 694 | target_arch=$(chroot "$mp" rpm -E '%_arch') | ||
1158 | 695 | r=$? | ||
1159 | 696 | ;; | ||
1160 | 697 | esac | ||
1161 | 698 | [ $r -eq 0 ] || { | ||
1162 | 699 | error "failed to get target architecture [$r]" | ||
1163 | 700 | return 1; | ||
1164 | 701 | } | ||
1165 | 702 | |||
1166 | 703 | # grub is not the bootloader you are looking for | ||
1167 | 704 | if [ "${target_arch}" = "s390x" ]; then | ||
1168 | 705 | return 0; | ||
1169 | 706 | fi | ||
1170 | 707 | |||
1171 | 708 | # set correct grub package | ||
1172 | 709 | local grub_name="" | ||
1173 | 710 | local grub_target="" | ||
1174 | 711 | case "$target_arch" in | ||
1175 | 712 | i386|amd64) | ||
1176 | 713 | # debian | ||
1177 | 714 | grub_name="grub-pc" | ||
1178 | 715 | grub_target="i386-pc" | ||
1179 | 716 | ;; | ||
1180 | 717 | x86_64) | ||
1181 | 718 | case $rhel_ver in | ||
1182 | 719 | 6) grub_name="grub";; | ||
1183 | 720 | 7|8) grub_name="grub2-pc";; | ||
1184 | 721 | *) | ||
1185 | 722 | error "Unknown rhel_ver [$rhel_ver]"; | ||
1186 | 723 | return 1; | ||
1187 | 724 | ;; | ||
1188 | 725 | esac | ||
1189 | 726 | grub_target="i386-pc" | ||
1190 | 727 | ;; | ||
1191 | 728 | esac | ||
1192 | 729 | if [ "${target_arch#ppc64}" != "${target_arch}" ]; then | ||
1193 | 730 | grub_name="grub-ieee1275" | ||
1194 | 731 | grub_target="powerpc-ieee1275" | ||
1195 | 732 | elif [ "$uefi" -ge 1 ]; then | ||
1196 | 733 | grub_name="grub-efi-$target_arch" | ||
1197 | 734 | case "$target_arch" in | ||
1198 | 735 | x86_64) | ||
1199 | 736 | # centos 7+, no centos6 support | ||
1200 | 737 | # grub2-efi-x64 installs a signed grub bootloader while | ||
1201 | 738 | # curtin uses grub2-efi-x64-modules to generate grubx64.efi. | ||
1202 | 739 | # Either works just check that one of them is installed. | ||
1203 | 740 | grub_name="grub2-efi-x64 grub2-efi-x64-modules" | ||
1204 | 741 | grub_target="x86_64-efi" | ||
1205 | 742 | ;; | ||
1206 | 743 | amd64) | ||
1207 | 744 | grub_target="x86_64-efi";; | ||
1208 | 745 | arm64) | ||
1209 | 746 | grub_target="arm64-efi";; | ||
1210 | 747 | esac | ||
1211 | 748 | fi | ||
1212 | 749 | |||
1213 | 750 | # check that the grub package is installed | ||
1214 | 751 | local r=$? | ||
1215 | 752 | case $os_family in | ||
1216 | 753 | debian) | ||
1217 | 754 | tmp=$(chroot "$mp" dpkg-query --show \ | ||
1218 | 755 | --showformat='${Status}\n' $grub_name) | ||
1219 | 756 | r=$? | ||
1220 | 757 | ;; | ||
1221 | 758 | redhat) | ||
1222 | 759 | tmp=$(chroot "$mp" rpm -q \ | ||
1223 | 760 | --queryformat='install ok installed\n' $grub_name) | ||
1224 | 761 | r=$? | ||
1225 | 762 | ;; | ||
1226 | 763 | esac | ||
1227 | 764 | if [ $r -ne 0 -a $r -ne 1 ]; then | ||
1228 | 765 | error "failed to check if $grub_name installed"; | ||
1229 | 766 | return 1; | ||
1230 | 767 | fi | ||
1231 | 768 | # Check that any of the packages in $grub_name are installed. If | ||
1232 | 769 | # grub_name contains multiple packages, as it does for CentOS 7+, | ||
1233 | 770 | # only one package has to be installed for this to pass. | ||
1234 | 771 | if ! echo $tmp | grep -q 'install ok installed'; then | ||
1235 | 772 | debug 1 "$grub_name not installed, not doing anything" | ||
1236 | 773 | return 1 | ||
1237 | 774 | fi | ||
1238 | 775 | |||
1239 | 776 | local grub_d="etc/default/grub.d" | ||
1240 | 777 | # ubuntu writes to /etc/default/grub.d/50-curtin-settings.cfg | ||
1241 | 778 | # to avoid tripping prompts on upgrade LP: #564853 | ||
1242 | 779 | local mygrub_cfg="$grub_d/50-curtin-settings.cfg" | ||
1243 | 780 | case $os_family in | ||
1244 | 781 | redhat) | ||
1245 | 782 | grub_d="etc/default" | ||
1246 | 783 | mygrub_cfg="etc/default/grub";; | ||
1247 | 784 | esac | ||
1248 | 785 | [ -d "$mp/$grub_d" ] || mkdir -p "$mp/$grub_d" || | ||
1249 | 786 | { error "Failed to create $grub_d"; return 1; } | ||
1250 | 787 | |||
1251 | 788 | # LP: #1179940 . The 50-cloudig-settings.cfg file is written by the cloud | ||
1252 | 789 | # images build and defines/override some settings. Disable it. | ||
1253 | 790 | local cicfg="$grub_d/50-cloudimg-settings.cfg" | ||
1254 | 791 | if [ -f "$mp/$cicfg" ]; then | ||
1255 | 792 | debug 1 "moved $cicfg out of the way" | ||
1256 | 793 | mv "$mp/$cicfg" "$mp/$cicfg.disabled" | ||
1257 | 794 | fi | ||
1258 | 795 | |||
1259 | 796 | # get the user provided / carry-over kernel arguments | ||
1260 | 797 | local newargs="" | ||
1261 | 798 | read cmdline < /proc/cmdline && | ||
1262 | 799 | get_carryover_params "$cmdline" && newargs="$_RET" || { | ||
1263 | 800 | error "Failed to get carryover parrameters from cmdline"; | ||
1264 | 801 | return 1; | ||
1265 | 802 | } | ||
1266 | 803 | # always append rd.auto=1 for centos | ||
1267 | 804 | case $os_family in | ||
1268 | 805 | redhat) | ||
1269 | 806 | newargs="${newargs:+${newargs} }rd.auto=1";; | ||
1270 | 807 | esac | ||
1271 | 808 | debug 1 "carryover command line params '$newargs'" | ||
1272 | 809 | |||
1273 | 810 | if [ "${REPLACE_GRUB_LINUX_DEFAULT:-1}" != "0" ]; then | ||
1274 | 811 | apply_grub_cmdline_linux_default "$mp" "$newargs" || { | ||
1275 | 812 | error "Failed to apply grub cmdline." | ||
1276 | 813 | return 1 | ||
1277 | 814 | } | ||
1278 | 815 | fi | ||
1279 | 816 | |||
1280 | 817 | if [ "${DISABLE_OS_PROBER:-1}" == "1" ]; then | ||
1281 | 818 | { | ||
1282 | 819 | echo "# Curtin disable grub os prober that might find other OS installs." | ||
1283 | 820 | echo "GRUB_DISABLE_OS_PROBER=true" | ||
1284 | 821 | } >> "$mp/$mygrub_cfg" | ||
1285 | 822 | fi | ||
1286 | 823 | |||
1287 | 824 | if [ -n "${GRUB_TERMINAL}" ]; then | ||
1288 | 825 | { | ||
1289 | 826 | echo "# Curtin configured GRUB_TERMINAL value" | ||
1290 | 827 | echo "GRUB_TERMINAL=${GRUB_TERMINAL}" | ||
1291 | 828 | } >> "$mp/$mygrub_cfg" | ||
1292 | 829 | fi | ||
1293 | 830 | |||
1294 | 831 | debug 1 "processing grubdevs values for expansion if needed" | ||
1295 | 832 | local short="" bd="" grubdev grubdevs_new="" | ||
1296 | 833 | grubdevs_new=() | ||
1297 | 834 | for grubdev in "${grubdevs[@]}"; do | ||
1298 | 835 | if is_md "$grubdev"; then | ||
1299 | 836 | debug 1 "$grubdev is raid, find members" | ||
1300 | 837 | short=${grubdev##*/} | ||
1301 | 838 | for bd in "/sys/block/$short/slaves/"/*; do | ||
1302 | 839 | [ -d "$bd" ] || continue | ||
1303 | 840 | bd=${bd##*/} | ||
1304 | 841 | bd="/dev/${bd%[0-9]}" # FIXME: part2bd | ||
1305 | 842 | debug 1 "Add dev $bd to grubdevs_new" | ||
1306 | 843 | grubdevs_new[${#grubdevs_new[@]}]="$bd" | ||
1307 | 844 | done | ||
1308 | 845 | else | ||
1309 | 846 | debug 1 "Found dev [$grubdev] add to grubdevs_new" | ||
1310 | 847 | grubdevs_new[${#grubdevs_new[@]}]="$grubdev" | ||
1311 | 848 | fi | ||
1312 | 849 | done | ||
1313 | 850 | grubdevs=( "${grubdevs_new[@]}" ) | ||
1314 | 851 | debug 1 "updated grubdevs: [${grubdevs[@]}]" | ||
1315 | 852 | |||
1316 | 853 | if [ "$uefi" -ge 1 ]; then | ||
1317 | 854 | nvram="--no-nvram" | ||
1318 | 855 | if [ "$update_nvram" -ge 1 ]; then | ||
1319 | 856 | nvram="" | ||
1320 | 857 | fi | ||
1321 | 858 | debug 1 "number of entries in grubdevs_new: ${#grubdevs[@]}" | ||
1322 | 859 | if [ "${#grubdevs_new[@]}" -eq 1 ] && [ -b "${grubdevs_new[0]}" ]; then | ||
1323 | 860 | debug 1 "Found a single entry in grubdevs, ${grubdevs_new[0]}" | ||
1324 | 861 | # Currently UEFI can only be pointed to one system partition. If | ||
1325 | 862 | # for some reason multiple install locations are given only use the | ||
1326 | 863 | # first. | ||
1327 | 864 | efi_dev="${grubdevs_new[0]}" | ||
1328 | 865 | debug 1 "efi_dev=[${efi_dev}]" | ||
1329 | 866 | elif [ "${#grubdevs_new[@]}" -gt 1 ]; then | ||
1330 | 867 | error "Only one grub device supported on UEFI!" | ||
1331 | 868 | exit 1 | ||
1332 | 869 | else | ||
1333 | 870 | debug 1 "no storage config, parsing /proc/mounts with awk" | ||
1334 | 871 | # If no storage configuration was given try to determine the system | ||
1335 | 872 | # partition. | ||
1336 | 873 | efi_dev=$(awk -v "MP=${mp}/boot/efi" '$2 == MP { print $1 }' /proc/mounts) | ||
1337 | 874 | debug 1 "efi_dev=[${efi_dev}]" | ||
1338 | 875 | [ -n "$efi_dev" ] || { | ||
1339 | 876 | error "Failed to find efi device from parsing /proc/mounts" | ||
1340 | 877 | return 1 | ||
1341 | 878 | } | ||
1342 | 879 | |||
1343 | 880 | fi | ||
1344 | 881 | # The partition number of block device name need to be determined here | ||
1345 | 882 | # so both getting the UEFI device from Curtin config and discovering it | ||
1346 | 883 | # work. | ||
1347 | 884 | efi_part_num=$(cat /sys/class/block/$(basename $efi_dev)/partition) | ||
1348 | 885 | debug 1 "efi_part_num: $efi_part_num" | ||
1349 | 886 | [ -n "${efi_part_num}" ] || { | ||
1350 | 887 | error "Failed to determine $efi_dev partition number" | ||
1351 | 888 | return 1 | ||
1352 | 889 | } | ||
1353 | 890 | efi_disk=$(get_parent_disk "$efi_dev") | ||
1354 | 891 | debug 1 "efi_disk: [$efi_disk]" | ||
1355 | 892 | [ -b "${efi_disk}" ] || { | ||
1356 | 893 | error "${efi_disk} is not a valid block device" | ||
1357 | 894 | return 1 | ||
1358 | 895 | } | ||
1359 | 896 | debug 1 "curtin uefi: installing ${grub_name} to: /boot/efi" | ||
1360 | 897 | chroot "$mp" env DEBIAN_FRONTEND=noninteractive sh -exc ' | ||
1361 | 898 | echo "before grub-install efiboot settings" | ||
1362 | 899 | efibootmgr -v || echo "WARN: efibootmgr exited $?" | ||
1363 | 900 | bootid="$4" | ||
1364 | 901 | efi_disk="$5" | ||
1365 | 902 | efi_part_num="$6" | ||
1366 | 903 | grubpost="" | ||
1367 | 904 | grubmulti="/usr/lib/grub/grub-multi-install" | ||
1368 | 905 | case $bootid in | ||
1369 | 906 | debian|ubuntu) | ||
1370 | 907 | grubcmd="grub-install" | ||
1371 | 908 | if [ -e "${grubmulti}" ]; then | ||
1372 | 909 | grubcmd="${grubmulti}" | ||
1373 | 910 | fi | ||
1374 | 911 | dpkg-reconfigure "$1" | ||
1375 | 912 | update-grub | ||
1376 | 913 | ;; | ||
1377 | 914 | centos|redhat|rhel) | ||
1378 | 915 | grubcmd="grub2-install" | ||
1379 | 916 | # RHEL uses redhat instead of the os_variant rhel for the bootid. | ||
1380 | 917 | if [ "$bootid" = "rhel" ]; then | ||
1381 | 918 | bootid="redhat" | ||
1382 | 919 | fi | ||
1383 | 920 | if [ -f /boot/efi/EFI/$bootid/grubx64.efi ]; then | ||
1384 | 921 | grubpost="grub2-mkconfig -o /boot/efi/EFI/$bootid/grub.cfg" | ||
1385 | 922 | else | ||
1386 | 923 | grubpost="grub2-mkconfig -o /boot/grub2/grub.cfg" | ||
1387 | 924 | fi | ||
1388 | 925 | ;; | ||
1389 | 926 | *) | ||
1390 | 927 | echo "Unsupported OS: $bootid" 1>&2 | ||
1391 | 928 | exit 1 | ||
1392 | 929 | ;; | ||
1393 | 930 | esac | ||
1394 | 931 | # grub-install in 12.04 does not contain --no-nvram, --target, | ||
1395 | 932 | # or --efi-directory | ||
1396 | 933 | target="--target=$2" | ||
1397 | 934 | no_nvram="$3" | ||
1398 | 935 | efi_dir="--efi-directory=/boot/efi" | ||
1399 | 936 | gi_out=$($grubcmd --help 2>&1) | ||
1400 | 937 | echo "$gi_out" | grep -q -- "$no_nvram" || no_nvram="" | ||
1401 | 938 | echo "$gi_out" | grep -q -- "--target" || target="" | ||
1402 | 939 | echo "$gi_out" | grep -q -- "--efi-directory" || efi_dir="" | ||
1403 | 940 | |||
1404 | 941 | # Do not overwrite grubx64.efi if it already exists. grub-install | ||
1405 | 942 | # generates grubx64.efi and overwrites any existing binary in | ||
1406 | 943 | # /boot/efi/EFI/$bootid. This binary is not signed and will cause | ||
1407 | 944 | # secure boot to fail. | ||
1408 | 945 | # | ||
1409 | 946 | # CentOS, RHEL, Fedora ship the signed boot loader in the package | ||
1410 | 947 | # grub2-efi-x64 which installs the signed boot loader to | ||
1411 | 948 | # /boot/efi/EFI/$bootid/grubx64.efi. All Curtin has to do is | ||
1412 | 949 | # configure the firmware. This mirrors what Anaconda does. | ||
1413 | 950 | # | ||
1414 | 951 | # Debian and Ubuntu come with a patched version of grub which | ||
1415 | 952 | # add the install flag --uefi-secure-boot which is enabled by | ||
1416 | 953 | # default. When enabled if a signed version of grub exists on | ||
1417 | 954 | # the filesystem it will be copied into /boot/efi/EFI/$bootid. | ||
1418 | 955 | # Stock Ubuntu images do not ship with anything in /boot. Those | ||
1419 | 956 | # files are generated by installing a kernel and grub. | ||
1420 | 957 | echo "Dumping /boot/efi contents" | ||
1421 | 958 | find /boot/efi | ||
1422 | 959 | echo "Checking for existing EFI grub entry on ESP" | ||
1423 | 960 | if [ "$grubcmd" = "grub2-install" -a -f /boot/efi/EFI/$bootid/grubx64.efi ]; then | ||
1424 | 961 | if [ -z "$no_nvram" ]; then | ||
1425 | 962 | # UEFI firmware should be pointed to the shim if available to | ||
1426 | 963 | # enable secure boot. | ||
1427 | 964 | for boot_uefi in \ | ||
1428 | 965 | /boot/efi/EFI/$bootid/shimx64.efi \ | ||
1429 | 966 | /boot/efi/EFI/BOOT/BOOTX64.EFI \ | ||
1430 | 967 | /boot/efi/EFI/$bootid/grubx64.efi; do | ||
1431 | 968 | if [ -f $boot_uefi ]; then | ||
1432 | 969 | break | ||
1433 | 970 | fi | ||
1434 | 971 | done | ||
1435 | 972 | loader=$(echo ${boot_uefi##/boot/efi} | sed "s|/|\\\|g") | ||
1436 | 973 | efibootmgr --create --write-signature --label $bootid \ | ||
1437 | 974 | --disk $efi_disk --part $efi_part_num --loader $loader | ||
1438 | 975 | rc=$? | ||
1439 | 976 | [ "$rc" != "0" ] && { exit $rc; } | ||
1440 | 977 | else | ||
1441 | 978 | echo "skip EFI entry creation due to \"$no_nvram\" flag" | ||
1442 | 979 | fi | ||
1443 | 980 | else | ||
1444 | 981 | echo "No previous EFI grub entry found on ESP, use $grubcmd" | ||
1445 | 982 | if [ "${grubcmd}" = "${grubmulti}" ]; then | ||
1446 | 983 | $grubcmd | ||
1447 | 984 | else | ||
1448 | 985 | $grubcmd $target $efi_dir \ | ||
1449 | 986 | --bootloader-id=$bootid --recheck $no_nvram | ||
1450 | 987 | fi | ||
1451 | 988 | fi | ||
1452 | 989 | [ -z "$grubpost" ] || $grubpost;' \ | ||
1453 | 990 | -- "$grub_name" "$grub_target" "$nvram" "$os_variant" "$efi_disk" "$efi_part_num" </dev/null || | ||
1454 | 991 | { error "failed to install grub!"; return 1; } | ||
1455 | 992 | |||
1456 | 993 | chroot "$mp" sh -exc ' | ||
1457 | 994 | echo "after grub-install efiboot settings" | ||
1458 | 995 | efibootmgr -v || echo "WARN: efibootmgr exited $?" | ||
1459 | 996 | ' -- </dev/null || | ||
1460 | 997 | { error "failed to list efi boot entries!"; return 1; } | ||
1461 | 998 | else | ||
1462 | 999 | # Note: dpkg-reconfigure calls grub-install on ppc64 | ||
1463 | 1000 | # this means that using '--no-nvram' below ends up | ||
1464 | 1001 | # failing very oddly. This is because grub's post-inst | ||
1465 | 1002 | # runs grub-install with no target. That ends up | ||
1466 | 1003 | # updating nvram badly, and then the grub-install would | ||
1467 | 1004 | # not fix it because of the no-nvram there. | ||
1468 | 1005 | debug 1 "curtin non-uefi: installing ${grub_name} to: ${grubdevs[*]}" | ||
1469 | 1006 | chroot "$mp" env DEBIAN_FRONTEND=noninteractive sh -exc ' | ||
1470 | 1007 | pkg=$1; shift; | ||
1471 | 1008 | bootid=$1; shift; | ||
1472 | 1009 | bootver=$1; shift; | ||
1473 | 1010 | grubpost="" | ||
1474 | 1011 | case $bootid in | ||
1475 | 1012 | debian|ubuntu) | ||
1476 | 1013 | grubcmd="grub-install" | ||
1477 | 1014 | dpkg-reconfigure "$pkg" | ||
1478 | 1015 | update-grub | ||
1479 | 1016 | ;; | ||
1480 | 1017 | centos|redhat|rhel) | ||
1481 | 1018 | case $bootver in | ||
1482 | 1019 | 6) grubcmd="grub-install";; | ||
1483 | 1020 | 7|8) grubcmd="grub2-install" | ||
1484 | 1021 | grubpost="grub2-mkconfig -o /boot/grub2/grub.cfg";; | ||
1485 | 1022 | *) | ||
1486 | 1023 | echo "Unknown rhel_ver [$bootver]" | ||
1487 | 1024 | exit 1 | ||
1488 | 1025 | esac | ||
1489 | 1026 | ;; | ||
1490 | 1027 | *) | ||
1491 | 1028 | echo "Unsupported OS: $bootid"; 1>&2 | ||
1492 | 1029 | exit 1 | ||
1493 | 1030 | ;; | ||
1494 | 1031 | esac | ||
1495 | 1032 | for d in "$@"; do | ||
1496 | 1033 | echo $grubcmd "$d"; | ||
1497 | 1034 | $grubcmd "$d" || exit; done | ||
1498 | 1035 | [ -z "$grubpost" ] || $grubpost;' \ | ||
1499 | 1036 | -- "${grub_name}" "${os_variant}" "${rhel_ver}" "${grubdevs[@]}" </dev/null || | ||
1500 | 1037 | { error "failed to install grub!"; return 1; } | ||
1501 | 1038 | fi | ||
1502 | 1039 | |||
1503 | 1040 | if [ -n "${mp_efi}" ]; then | ||
1504 | 1041 | umount "$mp_efi" || | ||
1505 | 1042 | { error "failed to unmount $mp_efi"; return 1; } | ||
1506 | 1043 | fi | ||
1507 | 1044 | |||
1508 | 1045 | return | ||
1509 | 1046 | } | ||
1510 | 1047 | |||
1511 | 1048 | # vi: ts=4 expandtab syntax=sh | 470 | # vi: ts=4 expandtab syntax=sh |
1512 | diff --git a/helpers/install-grub b/helpers/install-grub | |||
1513 | 1049 | deleted file mode 100755 | 471 | deleted file mode 100755 |
1514 | index e1bfb23..0000000 | |||
1515 | --- a/helpers/install-grub | |||
1516 | +++ /dev/null | |||
1517 | @@ -1,7 +0,0 @@ | |||
1518 | 1 | #!/bin/bash | ||
1519 | 2 | # This file is part of curtin. See LICENSE file for copyright and license info. | ||
1520 | 3 | |||
1521 | 4 | [ "${0%/*}" = "$0" ] && . ./common || . "${0%/*}/common" | ||
1522 | 5 | install_grub "$@" | ||
1523 | 6 | |||
1524 | 7 | # vi: ts=4 expandtab syntax=sh | ||
1525 | diff --git a/requirements.txt b/requirements.txt | |||
1526 | index 9066728..6afa3b8 100644 | |||
1527 | --- a/requirements.txt | |||
1528 | +++ b/requirements.txt | |||
1529 | @@ -2,3 +2,6 @@ pyyaml | |||
1530 | 2 | oauthlib | 2 | oauthlib |
1531 | 3 | # For validation of storate configuration format | 3 | # For validation of storate configuration format |
1532 | 4 | jsonschema | 4 | jsonschema |
1533 | 5 | # Dependency of jsonschema. | ||
1534 | 6 | # Version 0.16.0 is the latest version supporting Python < 3.5. | ||
1535 | 7 | pyrsistent==0.16.0 | ||
1536 | diff --git a/tests/data/multipath-nvme.txt b/tests/data/multipath-nvme.txt | |||
1537 | 5 | new file mode 100644 | 8 | new file mode 100644 |
1538 | index 0000000..30b59e4 | |||
1539 | --- /dev/null | |||
1540 | +++ b/tests/data/multipath-nvme.txt | |||
1541 | @@ -0,0 +1 @@ | |||
1542 | 1 | name='nqn.1994-11.com.samsung:nvme:PM1725a:HHHL:S3RVNA0J300208 :nsid.1' multipath='eui.335256304a3002080025384100000001' sysfs='nvme0n1' paths='1' | ||
1543 | diff --git a/tests/unittests/helpers.py b/tests/unittests/helpers.py | |||
1544 | index 2f5e51a..64a79ca 100644 | |||
1545 | --- a/tests/unittests/helpers.py | |||
1546 | +++ b/tests/unittests/helpers.py | |||
1547 | @@ -2,11 +2,13 @@ | |||
1548 | 2 | 2 | ||
1549 | 3 | import imp | 3 | import imp |
1550 | 4 | import importlib | 4 | import importlib |
1551 | 5 | import logging | ||
1552 | 5 | import mock | 6 | import mock |
1553 | 6 | import os | 7 | import os |
1554 | 7 | import random | 8 | import random |
1555 | 8 | import shutil | 9 | import shutil |
1556 | 9 | import string | 10 | import string |
1557 | 11 | import sys | ||
1558 | 10 | import tempfile | 12 | import tempfile |
1559 | 11 | from unittest import TestCase, skipIf | 13 | from unittest import TestCase, skipIf |
1560 | 12 | from contextlib import contextmanager | 14 | from contextlib import contextmanager |
1561 | @@ -55,6 +57,7 @@ def skipUnlessJsonSchema(): | |||
1562 | 55 | class CiTestCase(TestCase): | 57 | class CiTestCase(TestCase): |
1563 | 56 | """Common testing class which all curtin unit tests subclass.""" | 58 | """Common testing class which all curtin unit tests subclass.""" |
1564 | 57 | 59 | ||
1565 | 60 | with_logs = False | ||
1566 | 58 | allowed_subp = False | 61 | allowed_subp = False |
1567 | 59 | SUBP_SHELL_TRUE = "shell=True" | 62 | SUBP_SHELL_TRUE = "shell=True" |
1568 | 60 | 63 | ||
1569 | @@ -69,6 +72,21 @@ class CiTestCase(TestCase): | |||
1570 | 69 | 72 | ||
1571 | 70 | def setUp(self): | 73 | def setUp(self): |
1572 | 71 | super(CiTestCase, self).setUp() | 74 | super(CiTestCase, self).setUp() |
1573 | 75 | if self.with_logs: | ||
1574 | 76 | # Create a log handler so unit tests can search expected logs. | ||
1575 | 77 | self.logger = logging.getLogger() | ||
1576 | 78 | if sys.version_info[0] == 2: | ||
1577 | 79 | import StringIO | ||
1578 | 80 | self.logs = StringIO.StringIO() | ||
1579 | 81 | else: | ||
1580 | 82 | import io | ||
1581 | 83 | self.logs = io.StringIO() | ||
1582 | 84 | formatter = logging.Formatter('%(levelname)s: %(message)s') | ||
1583 | 85 | handler = logging.StreamHandler(self.logs) | ||
1584 | 86 | handler.setFormatter(formatter) | ||
1585 | 87 | self.old_handlers = self.logger.handlers | ||
1586 | 88 | self.logger.handlers = [handler] | ||
1587 | 89 | |||
1588 | 72 | if self.allowed_subp is True: | 90 | if self.allowed_subp is True: |
1589 | 73 | util.subp = _real_subp | 91 | util.subp = _real_subp |
1590 | 74 | else: | 92 | else: |
1591 | diff --git a/tests/unittests/test_block.py b/tests/unittests/test_block.py | |||
1592 | index c62c153..78e331d 100644 | |||
1593 | --- a/tests/unittests/test_block.py | |||
1594 | +++ b/tests/unittests/test_block.py | |||
1595 | @@ -179,6 +179,18 @@ class TestBlock(CiTestCase): | |||
1596 | 179 | byid_path = block.disk_to_byid_path('/dev/sdb') | 179 | byid_path = block.disk_to_byid_path('/dev/sdb') |
1597 | 180 | self.assertEqual(mapping.get('/dev/sdb'), byid_path) | 180 | self.assertEqual(mapping.get('/dev/sdb'), byid_path) |
1598 | 181 | 181 | ||
1599 | 182 | @mock.patch("curtin.block.os.path.exists") | ||
1600 | 183 | def test__get_dev_disk_by_prefix_returns_empty_dict(self, m_exists): | ||
1601 | 184 | """ _get_disk_by_prefix returns empty dict prefix dir does not exit """ | ||
1602 | 185 | m_exists.return_value = False | ||
1603 | 186 | self.assertEqual({}, block._get_dev_disk_by_prefix("/dev/disk/by-id")) | ||
1604 | 187 | |||
1605 | 188 | @mock.patch("curtin.block.os.path.exists") | ||
1606 | 189 | def test_disk_to_byid_returns_none_if_disk_byid_missing(self, m_exists): | ||
1607 | 190 | """ disk_to_byid path returns None if /dev/disk/by-id is missing """ | ||
1608 | 191 | m_exists.return_value = False | ||
1609 | 192 | self.assertEqual(None, block.disk_to_byid_path('/dev/sdb')) | ||
1610 | 193 | |||
1611 | 182 | 194 | ||
1612 | 183 | class TestSysBlockPath(CiTestCase): | 195 | class TestSysBlockPath(CiTestCase): |
1613 | 184 | @mock.patch("curtin.block.get_blockdev_for_partition") | 196 | @mock.patch("curtin.block.get_blockdev_for_partition") |
1614 | diff --git a/tests/unittests/test_block_multipath.py b/tests/unittests/test_block_multipath.py | |||
1615 | index 2101eae..96cbcba 100644 | |||
1616 | --- a/tests/unittests/test_block_multipath.py | |||
1617 | +++ b/tests/unittests/test_block_multipath.py | |||
1618 | @@ -39,6 +39,20 @@ class TestMultipath(CiTestCase): | |||
1619 | 39 | multipath.show_maps()) | 39 | multipath.show_maps()) |
1620 | 40 | self.m_subp.assert_called_with(expected, capture=True) | 40 | self.m_subp.assert_called_with(expected, capture=True) |
1621 | 41 | 41 | ||
1622 | 42 | def test_show_maps_nvme(self): | ||
1623 | 43 | """verify show_maps extracts mulitpath map data correctly.""" | ||
1624 | 44 | NVME_MP = multipath.util.load_file('tests/data/multipath-nvme.txt') | ||
1625 | 45 | self.m_subp.return_value = (NVME_MP, "") | ||
1626 | 46 | expected = ['multipathd', 'show', 'maps', 'raw', 'format', | ||
1627 | 47 | multipath.SHOW_MAPS_FMT] | ||
1628 | 48 | self.assertEqual([ | ||
1629 | 49 | {'name': | ||
1630 | 50 | ('nqn.1994-11.com.samsung:nvme:PM1725a:HHHL:S3RVNA0J300208 ' | ||
1631 | 51 | ':nsid.1'), | ||
1632 | 52 | 'multipath': 'eui.335256304a3002080025384100000001', | ||
1633 | 53 | 'sysfs': 'nvme0n1', 'paths': '1'}], multipath.show_maps()) | ||
1634 | 54 | self.m_subp.assert_called_with(expected, capture=True) | ||
1635 | 55 | |||
1636 | 42 | def test_is_mpath_device_true(self): | 56 | def test_is_mpath_device_true(self): |
1637 | 43 | """is_mpath_device returns true if dev DM_UUID starts with mpath-""" | 57 | """is_mpath_device returns true if dev DM_UUID starts with mpath-""" |
1638 | 44 | self.m_udev.udevadm_info.return_value = {'DM_UUID': 'mpath-mpatha-foo'} | 58 | self.m_udev.udevadm_info.return_value = {'DM_UUID': 'mpath-mpatha-foo'} |
1639 | diff --git a/tests/unittests/test_commands_block_meta.py b/tests/unittests/test_commands_block_meta.py | |||
1640 | index b768cdc..d954296 100644 | |||
1641 | --- a/tests/unittests/test_commands_block_meta.py | |||
1642 | +++ b/tests/unittests/test_commands_block_meta.py | |||
1643 | @@ -1779,6 +1779,7 @@ class TestRaidHandler(CiTestCase): | |||
1644 | 1779 | def setUp(self): | 1779 | def setUp(self): |
1645 | 1780 | super(TestRaidHandler, self).setUp() | 1780 | super(TestRaidHandler, self).setUp() |
1646 | 1781 | 1781 | ||
1647 | 1782 | orig_md_path = block_meta.block.md_path | ||
1648 | 1782 | basepath = 'curtin.commands.block_meta.' | 1783 | basepath = 'curtin.commands.block_meta.' |
1649 | 1783 | self.add_patch(basepath + 'get_path_to_storage_volume', 'm_getpath') | 1784 | self.add_patch(basepath + 'get_path_to_storage_volume', 'm_getpath') |
1650 | 1784 | self.add_patch(basepath + 'util', 'm_util') | 1785 | self.add_patch(basepath + 'util', 'm_util') |
1651 | @@ -1787,6 +1788,10 @@ class TestRaidHandler(CiTestCase): | |||
1652 | 1787 | self.add_patch(basepath + 'block', 'm_block') | 1788 | self.add_patch(basepath + 'block', 'm_block') |
1653 | 1788 | self.add_patch(basepath + 'udevadm_settle', 'm_uset') | 1789 | self.add_patch(basepath + 'udevadm_settle', 'm_uset') |
1654 | 1789 | 1790 | ||
1655 | 1791 | # The behavior of this function is being directly tested in | ||
1656 | 1792 | # these tests, so we can't mock it | ||
1657 | 1793 | self.m_block.md_path = orig_md_path | ||
1658 | 1794 | |||
1659 | 1790 | self.target = "my_target" | 1795 | self.target = "my_target" |
1660 | 1791 | self.config = { | 1796 | self.config = { |
1661 | 1792 | 'storage': { | 1797 | 'storage': { |
1662 | @@ -1850,12 +1855,40 @@ class TestRaidHandler(CiTestCase): | |||
1663 | 1850 | block_meta.extract_storage_ordered_dict(self.config)) | 1855 | block_meta.extract_storage_ordered_dict(self.config)) |
1664 | 1851 | self.m_util.load_command_environment.return_value = {'fstab': None} | 1856 | self.m_util.load_command_environment.return_value = {'fstab': None} |
1665 | 1852 | 1857 | ||
1666 | 1858 | def test_md_name(self): | ||
1667 | 1859 | input_to_result = [ | ||
1668 | 1860 | ('md1', '/dev/md1'), | ||
1669 | 1861 | ('os-raid1', '/dev/md/os-raid1'), | ||
1670 | 1862 | ('md/os-raid1', '/dev/md/os-raid1'), | ||
1671 | 1863 | ('/dev/md1', '/dev/md1'), | ||
1672 | 1864 | ('/dev/md/os-raid1', '/dev/md/os-raid1'), | ||
1673 | 1865 | ('bad/path', ValueError) | ||
1674 | 1866 | ] | ||
1675 | 1867 | for index, test in enumerate(input_to_result): | ||
1676 | 1868 | param, expected = test | ||
1677 | 1869 | self.storage_config['mddevice']['name'] = param | ||
1678 | 1870 | try: | ||
1679 | 1871 | block_meta.raid_handler(self.storage_config['mddevice'], | ||
1680 | 1872 | self.storage_config) | ||
1681 | 1873 | except ValueError: | ||
1682 | 1874 | if param in ['bad/path']: | ||
1683 | 1875 | continue | ||
1684 | 1876 | else: | ||
1685 | 1877 | raise | ||
1686 | 1878 | |||
1687 | 1879 | actual = self.m_mdadm.mdadm_create.call_args_list[index][0][0] | ||
1688 | 1880 | self.assertEqual( | ||
1689 | 1881 | expected, | ||
1690 | 1882 | actual, | ||
1691 | 1883 | "Expected {} to result in mdadm being called with {}. " | ||
1692 | 1884 | "mdadm instead called with {}".format(param, expected, actual) | ||
1693 | 1885 | ) | ||
1694 | 1886 | |||
1695 | 1853 | def test_raid_handler(self): | 1887 | def test_raid_handler(self): |
1696 | 1854 | """ raid_handler creates raid device. """ | 1888 | """ raid_handler creates raid device. """ |
1697 | 1855 | devices = [self.random_string(), self.random_string(), | 1889 | devices = [self.random_string(), self.random_string(), |
1698 | 1856 | self.random_string()] | 1890 | self.random_string()] |
1699 | 1857 | md_devname = '/dev/' + self.storage_config['mddevice']['name'] | 1891 | md_devname = '/dev/' + self.storage_config['mddevice']['name'] |
1700 | 1858 | self.m_block.dev_path.return_value = '/dev/md0' | ||
1701 | 1859 | self.m_getpath.side_effect = iter(devices) | 1892 | self.m_getpath.side_effect = iter(devices) |
1702 | 1860 | block_meta.raid_handler(self.storage_config['mddevice'], | 1893 | block_meta.raid_handler(self.storage_config['mddevice'], |
1703 | 1861 | self.storage_config) | 1894 | self.storage_config) |
1704 | @@ -1868,7 +1901,6 @@ class TestRaidHandler(CiTestCase): | |||
1705 | 1868 | 1901 | ||
1706 | 1869 | devices = [self.random_string(), self.random_string(), | 1902 | devices = [self.random_string(), self.random_string(), |
1707 | 1870 | self.random_string()] | 1903 | self.random_string()] |
1708 | 1871 | self.m_block.dev_path.return_value = '/dev/md0' | ||
1709 | 1872 | self.m_getpath.side_effect = iter(devices) | 1904 | self.m_getpath.side_effect = iter(devices) |
1710 | 1873 | m_verify.return_value = True | 1905 | m_verify.return_value = True |
1711 | 1874 | self.storage_config['mddevice']['preserve'] = True | 1906 | self.storage_config['mddevice']['preserve'] = True |
1712 | @@ -1882,7 +1914,6 @@ class TestRaidHandler(CiTestCase): | |||
1713 | 1882 | devices = [self.random_string(), self.random_string(), | 1914 | devices = [self.random_string(), self.random_string(), |
1714 | 1883 | self.random_string()] | 1915 | self.random_string()] |
1715 | 1884 | md_devname = '/dev/' + self.storage_config['mddevice']['name'] | 1916 | md_devname = '/dev/' + self.storage_config['mddevice']['name'] |
1716 | 1885 | self.m_block.dev_path.return_value = '/dev/md0' | ||
1717 | 1886 | self.m_getpath.side_effect = iter(devices) | 1917 | self.m_getpath.side_effect = iter(devices) |
1718 | 1887 | self.m_mdadm.md_check.return_value = True | 1918 | self.m_mdadm.md_check.return_value = True |
1719 | 1888 | self.storage_config['mddevice']['preserve'] = True | 1919 | self.storage_config['mddevice']['preserve'] = True |
1720 | @@ -1898,7 +1929,6 @@ class TestRaidHandler(CiTestCase): | |||
1721 | 1898 | devices = [self.random_string(), self.random_string(), | 1929 | devices = [self.random_string(), self.random_string(), |
1722 | 1899 | self.random_string()] | 1930 | self.random_string()] |
1723 | 1900 | md_devname = '/dev/' + self.storage_config['mddevice']['name'] | 1931 | md_devname = '/dev/' + self.storage_config['mddevice']['name'] |
1724 | 1901 | self.m_block.dev_path.return_value = '/dev/md0' | ||
1725 | 1902 | self.m_getpath.side_effect = iter(devices) | 1932 | self.m_getpath.side_effect = iter(devices) |
1726 | 1903 | self.m_mdadm.md_check.side_effect = iter([False, True]) | 1933 | self.m_mdadm.md_check.side_effect = iter([False, True]) |
1727 | 1904 | self.storage_config['mddevice']['preserve'] = True | 1934 | self.storage_config['mddevice']['preserve'] = True |
1728 | @@ -1916,7 +1946,6 @@ class TestRaidHandler(CiTestCase): | |||
1729 | 1916 | devices = [self.random_string(), self.random_string(), | 1946 | devices = [self.random_string(), self.random_string(), |
1730 | 1917 | self.random_string()] | 1947 | self.random_string()] |
1731 | 1918 | md_devname = '/dev/' + self.storage_config['mddevice']['name'] | 1948 | md_devname = '/dev/' + self.storage_config['mddevice']['name'] |
1732 | 1919 | self.m_block.dev_path.return_value = '/dev/md0' | ||
1733 | 1920 | self.m_getpath.side_effect = iter(devices) | 1949 | self.m_getpath.side_effect = iter(devices) |
1734 | 1921 | self.m_mdadm.md_check.side_effect = iter([False, False]) | 1950 | self.m_mdadm.md_check.side_effect = iter([False, False]) |
1735 | 1922 | self.storage_config['mddevice']['preserve'] = True | 1951 | self.storage_config['mddevice']['preserve'] = True |
1736 | @@ -2557,4 +2586,115 @@ class TestVerifyPtableFlag(CiTestCase): | |||
1737 | 2557 | sfdisk_info=self.sfdisk_info_dos) | 2586 | sfdisk_info=self.sfdisk_info_dos) |
1738 | 2558 | 2587 | ||
1739 | 2559 | 2588 | ||
1740 | 2589 | class TestGetDevicePathsFromStorageConfig(CiTestCase): | ||
1741 | 2590 | |||
1742 | 2591 | def setUp(self): | ||
1743 | 2592 | super(TestGetDevicePathsFromStorageConfig, self).setUp() | ||
1744 | 2593 | base = 'curtin.commands.block_meta.' | ||
1745 | 2594 | self.add_patch(base + 'get_path_to_storage_volume', 'mock_getpath') | ||
1746 | 2595 | self.add_patch(base + 'os.path.exists', 'm_exists') | ||
1747 | 2596 | self.m_exists.return_value = True | ||
1748 | 2597 | self.mock_getpath.side_effect = self._getpath | ||
1749 | 2598 | self.prefix = '/test/dev/' | ||
1750 | 2599 | self.config = { | ||
1751 | 2600 | 'storage': { | ||
1752 | 2601 | 'version': 1, | ||
1753 | 2602 | 'config': [ | ||
1754 | 2603 | {'id': 'sda', | ||
1755 | 2604 | 'type': 'disk', | ||
1756 | 2605 | 'name': 'main_disk', | ||
1757 | 2606 | 'ptable': 'gpt', | ||
1758 | 2607 | 'serial': 'disk-a'}, | ||
1759 | 2608 | {'id': 'disk-sda-part-1', | ||
1760 | 2609 | 'type': 'partition', | ||
1761 | 2610 | 'device': 'sda', | ||
1762 | 2611 | 'name': 'bios_boot', | ||
1763 | 2612 | 'number': 1, | ||
1764 | 2613 | 'size': '1M', | ||
1765 | 2614 | 'flag': 'bios_grub'}, | ||
1766 | 2615 | {'id': 'disk-sda-part-2', | ||
1767 | 2616 | 'type': 'partition', | ||
1768 | 2617 | 'device': 'sda', | ||
1769 | 2618 | 'number': 2, | ||
1770 | 2619 | 'size': '5GB'}, | ||
1771 | 2620 | ], | ||
1772 | 2621 | } | ||
1773 | 2622 | } | ||
1774 | 2623 | self.disk1 = self.config['storage']['config'][0] | ||
1775 | 2624 | self.part1 = self.config['storage']['config'][1] | ||
1776 | 2625 | self.part2 = self.config['storage']['config'][2] | ||
1777 | 2626 | self.sconfig = self._sconfig(self.config) | ||
1778 | 2627 | |||
1779 | 2628 | def _sconfig(self, config): | ||
1780 | 2629 | return block_meta.extract_storage_ordered_dict(config) | ||
1781 | 2630 | |||
1782 | 2631 | def _getpath(self, item_id, _sconfig): | ||
1783 | 2632 | return self.prefix + item_id | ||
1784 | 2633 | |||
1785 | 2634 | def test_devpath_selects_disks_partitions_with_wipe_setting(self): | ||
1786 | 2635 | self.disk1['wipe'] = 'superblock' | ||
1787 | 2636 | self.part1['wipe'] = 'superblock' | ||
1788 | 2637 | self.sconfig = self._sconfig(self.config) | ||
1789 | 2638 | |||
1790 | 2639 | expected_devpaths = [ | ||
1791 | 2640 | self.prefix + self.disk1['id'], self.prefix + self.part1['id']] | ||
1792 | 2641 | result = block_meta.get_device_paths_from_storage_config(self.sconfig) | ||
1793 | 2642 | self.assertEqual(sorted(expected_devpaths), sorted(result)) | ||
1794 | 2643 | self.assertEqual([ | ||
1795 | 2644 | call(self.disk1['id'], self.sconfig), | ||
1796 | 2645 | call(self.part1['id'], self.sconfig)], | ||
1797 | 2646 | self.mock_getpath.call_args_list) | ||
1798 | 2647 | self.assertEqual( | ||
1799 | 2648 | sorted([call(devpath) for devpath in expected_devpaths]), | ||
1800 | 2649 | sorted(self.m_exists.call_args_list)) | ||
1801 | 2650 | |||
1802 | 2651 | def test_devpath_raises_exception_if_wipe_and_preserve_set(self): | ||
1803 | 2652 | self.disk1['wipe'] = 'superblock' | ||
1804 | 2653 | self.disk1['preserve'] = True | ||
1805 | 2654 | self.sconfig = self._sconfig(self.config) | ||
1806 | 2655 | |||
1807 | 2656 | with self.assertRaises(RuntimeError): | ||
1808 | 2657 | block_meta.get_device_paths_from_storage_config(self.sconfig) | ||
1809 | 2658 | self.assertEqual([], self.mock_getpath.call_args_list) | ||
1810 | 2659 | self.assertEqual([], self.m_exists.call_args_list) | ||
1811 | 2660 | |||
1812 | 2661 | def test_devpath_check_boolean_value_if_wipe_and_preserve_set(self): | ||
1813 | 2662 | self.disk1['wipe'] = 'superblock' | ||
1814 | 2663 | self.disk1['preserve'] = False | ||
1815 | 2664 | self.sconfig = self._sconfig(self.config) | ||
1816 | 2665 | |||
1817 | 2666 | expected_devpaths = [self.prefix + self.disk1['id']] | ||
1818 | 2667 | result = block_meta.get_device_paths_from_storage_config(self.sconfig) | ||
1819 | 2668 | self.assertEqual(expected_devpaths, result) | ||
1820 | 2669 | self.assertEqual( | ||
1821 | 2670 | [call(self.disk1['id'], self.sconfig)], | ||
1822 | 2671 | self.mock_getpath.call_args_list) | ||
1823 | 2672 | self.assertEqual( | ||
1824 | 2673 | sorted([call(devpath) for devpath in expected_devpaths]), | ||
1825 | 2674 | sorted(self.m_exists.call_args_list)) | ||
1826 | 2675 | |||
1827 | 2676 | def test_devpath_check_preserved_devices_skipped(self): | ||
1828 | 2677 | self.disk1['preserve'] = True | ||
1829 | 2678 | self.sconfig = self._sconfig(self.config) | ||
1830 | 2679 | |||
1831 | 2680 | result = block_meta.get_device_paths_from_storage_config(self.sconfig) | ||
1832 | 2681 | self.assertEqual([], result) | ||
1833 | 2682 | self.assertEqual([], self.mock_getpath.call_args_list) | ||
1834 | 2683 | self.assertEqual([], self.m_exists.call_args_list) | ||
1835 | 2684 | |||
1836 | 2685 | def test_devpath_check_missing_path_devices_skipped(self): | ||
1837 | 2686 | self.disk1['wipe'] = 'superblock' | ||
1838 | 2687 | self.sconfig = self._sconfig(self.config) | ||
1839 | 2688 | |||
1840 | 2689 | self.m_exists.return_value = False | ||
1841 | 2690 | result = block_meta.get_device_paths_from_storage_config(self.sconfig) | ||
1842 | 2691 | self.assertEqual([], result) | ||
1843 | 2692 | self.assertEqual( | ||
1844 | 2693 | [call(self.disk1['id'], self.sconfig)], | ||
1845 | 2694 | self.mock_getpath.call_args_list) | ||
1846 | 2695 | self.assertEqual( | ||
1847 | 2696 | [call(self.prefix + self.disk1['id'])], | ||
1848 | 2697 | self.m_exists.call_args_list) | ||
1849 | 2698 | |||
1850 | 2699 | |||
1851 | 2560 | # vi: ts=4 expandtab syntax=python | 2700 | # vi: ts=4 expandtab syntax=python |
1852 | diff --git a/tests/unittests/test_curthooks.py b/tests/unittests/test_curthooks.py | |||
1853 | index 2349456..e5fead3 100644 | |||
1854 | --- a/tests/unittests/test_curthooks.py | |||
1855 | +++ b/tests/unittests/test_curthooks.py | |||
1856 | @@ -1,5 +1,6 @@ | |||
1857 | 1 | # This file is part of curtin. See LICENSE file for copyright and license info. | 1 | # This file is part of curtin. See LICENSE file for copyright and license info. |
1858 | 2 | 2 | ||
1859 | 3 | import copy | ||
1860 | 3 | import os | 4 | import os |
1861 | 4 | from mock import call, patch | 5 | from mock import call, patch |
1862 | 5 | import textwrap | 6 | import textwrap |
1863 | @@ -10,7 +11,7 @@ from curtin import distro | |||
1864 | 10 | from curtin import util | 11 | from curtin import util |
1865 | 11 | from curtin import config | 12 | from curtin import config |
1866 | 12 | from curtin.reporter import events | 13 | from curtin.reporter import events |
1868 | 13 | from .helpers import CiTestCase, dir2dict, populate_dir | 14 | from .helpers import CiTestCase, dir2dict, populate_dir, random |
1869 | 14 | 15 | ||
1870 | 15 | 16 | ||
1871 | 16 | class TestGetFlashKernelPkgs(CiTestCase): | 17 | class TestGetFlashKernelPkgs(CiTestCase): |
1872 | @@ -531,12 +532,55 @@ class TestSetupZipl(CiTestCase): | |||
1873 | 531 | content) | 532 | content) |
1874 | 532 | 533 | ||
1875 | 533 | 534 | ||
1876 | 535 | class EfiOutput(object): | ||
1877 | 536 | |||
1878 | 537 | def __init__(self, current=None, order=None, entries=None): | ||
1879 | 538 | self.entries = {} | ||
1880 | 539 | if entries: | ||
1881 | 540 | for entry in entries: | ||
1882 | 541 | self.entries.update(entry) | ||
1883 | 542 | self.current = current | ||
1884 | 543 | self.order = order | ||
1885 | 544 | if not order and self.entries: | ||
1886 | 545 | self.order = sorted(self.entries.keys()) | ||
1887 | 546 | |||
1888 | 547 | def add_entry(self, bootnum=None, name=None, path=None, current=False): | ||
1889 | 548 | if not bootnum: | ||
1890 | 549 | bootnum = "%04x" % random.randint(0, 1000) | ||
1891 | 550 | if not name: | ||
1892 | 551 | name = CiTestCase.random_string() | ||
1893 | 552 | if not path: | ||
1894 | 553 | path = '' | ||
1895 | 554 | if bootnum not in self.entries: | ||
1896 | 555 | self.entries[bootnum] = {'name': name, 'path': path} | ||
1897 | 556 | if not self.order: | ||
1898 | 557 | self.order = [] | ||
1899 | 558 | self.order.append(bootnum) | ||
1900 | 559 | if current: | ||
1901 | 560 | self.current = bootnum | ||
1902 | 561 | |||
1903 | 562 | def set_order(self, new_order): | ||
1904 | 563 | self.order = new_order | ||
1905 | 564 | |||
1906 | 565 | def as_dict(self): | ||
1907 | 566 | output = {} | ||
1908 | 567 | if self.current: | ||
1909 | 568 | output['current'] = self.current | ||
1910 | 569 | if self.order: | ||
1911 | 570 | output['order'] = self.order | ||
1912 | 571 | output['entries'] = self.entries | ||
1913 | 572 | return output | ||
1914 | 573 | |||
1915 | 574 | |||
1916 | 534 | class TestSetupGrub(CiTestCase): | 575 | class TestSetupGrub(CiTestCase): |
1917 | 535 | 576 | ||
1918 | 577 | with_logs = True | ||
1919 | 578 | |||
1920 | 536 | def setUp(self): | 579 | def setUp(self): |
1921 | 537 | super(TestSetupGrub, self).setUp() | 580 | super(TestSetupGrub, self).setUp() |
1922 | 538 | self.target = self.tmp_dir() | 581 | self.target = self.tmp_dir() |
1923 | 539 | self.distro_family = distro.DISTROS.debian | 582 | self.distro_family = distro.DISTROS.debian |
1924 | 583 | self.variant = 'ubuntu' | ||
1925 | 540 | self.add_patch('curtin.distro.lsb_release', 'mock_lsb_release') | 584 | self.add_patch('curtin.distro.lsb_release', 'mock_lsb_release') |
1926 | 541 | self.mock_lsb_release.return_value = {'codename': 'xenial'} | 585 | self.mock_lsb_release.return_value = {'codename': 'xenial'} |
1927 | 542 | self.add_patch('curtin.util.is_uefi_bootable', | 586 | self.add_patch('curtin.util.is_uefi_bootable', |
1928 | @@ -556,7 +600,8 @@ class TestSetupGrub(CiTestCase): | |||
1929 | 556 | updated_cfg = { | 600 | updated_cfg = { |
1930 | 557 | 'install_devices': ['/dev/vdb'] | 601 | 'install_devices': ['/dev/vdb'] |
1931 | 558 | } | 602 | } |
1933 | 559 | curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family) | 603 | curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family, |
1934 | 604 | variant=self.variant) | ||
1935 | 560 | self.m_install_grub.assert_called_with( | 605 | self.m_install_grub.assert_called_with( |
1936 | 561 | ['/dev/vdb'], self.target, uefi=False, grubcfg=updated_cfg) | 606 | ['/dev/vdb'], self.target, uefi=False, grubcfg=updated_cfg) |
1937 | 562 | 607 | ||
1938 | @@ -588,7 +633,8 @@ class TestSetupGrub(CiTestCase): | |||
1939 | 588 | }, | 633 | }, |
1940 | 589 | } | 634 | } |
1941 | 590 | m_exists.return_value = True | 635 | m_exists.return_value = True |
1943 | 591 | curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family) | 636 | curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family, |
1944 | 637 | variant=self.variant) | ||
1945 | 592 | self.m_install_grub.assert_called_with( | 638 | self.m_install_grub.assert_called_with( |
1946 | 593 | ['/dev/vdb'], self.target, uefi=False, | 639 | ['/dev/vdb'], self.target, uefi=False, |
1947 | 594 | grubcfg={'install_devices': ['/dev/vdb']}) | 640 | grubcfg={'install_devices': ['/dev/vdb']}) |
1948 | @@ -638,7 +684,8 @@ class TestSetupGrub(CiTestCase): | |||
1949 | 638 | } | 684 | } |
1950 | 639 | m_exists.return_value = True | 685 | m_exists.return_value = True |
1951 | 640 | m_is_valid_device.side_effect = (False, True, False, True) | 686 | m_is_valid_device.side_effect = (False, True, False, True) |
1953 | 641 | curthooks.setup_grub(cfg, self.target, osfamily=distro.DISTROS.redhat) | 687 | curthooks.setup_grub(cfg, self.target, osfamily=distro.DISTROS.redhat, |
1954 | 688 | variant='centos') | ||
1955 | 642 | self.m_install_grub.assert_called_with( | 689 | self.m_install_grub.assert_called_with( |
1956 | 643 | ['/dev/vdb1'], self.target, uefi=True, | 690 | ['/dev/vdb1'], self.target, uefi=True, |
1957 | 644 | grubcfg={'update_nvram': False, 'install_devices': ['/dev/vdb1']} | 691 | grubcfg={'update_nvram': False, 'install_devices': ['/dev/vdb1']} |
1958 | @@ -650,7 +697,8 @@ class TestSetupGrub(CiTestCase): | |||
1959 | 650 | 'install_devices': None, | 697 | 'install_devices': None, |
1960 | 651 | }, | 698 | }, |
1961 | 652 | } | 699 | } |
1963 | 653 | curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family) | 700 | curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family, |
1964 | 701 | variant=self.variant) | ||
1965 | 654 | self.m_install_grub.assert_called_with( | 702 | self.m_install_grub.assert_called_with( |
1966 | 655 | ['none'], self.target, uefi=False, | 703 | ['none'], self.target, uefi=False, |
1967 | 656 | grubcfg={'install_devices': None} | 704 | grubcfg={'install_devices': None} |
1968 | @@ -681,7 +729,8 @@ class TestSetupGrub(CiTestCase): | |||
1969 | 681 | } | 729 | } |
1970 | 682 | } | 730 | } |
1971 | 683 | } | 731 | } |
1973 | 684 | curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family) | 732 | curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family, |
1974 | 733 | variant=self.variant) | ||
1975 | 685 | self.m_install_grub.assert_called_with( | 734 | self.m_install_grub.assert_called_with( |
1976 | 686 | ['/dev/vdb'], self.target, uefi=True, grubcfg=cfg.get('grub') | 735 | ['/dev/vdb'], self.target, uefi=True, grubcfg=cfg.get('grub') |
1977 | 687 | ) | 736 | ) |
1978 | @@ -721,7 +770,8 @@ class TestSetupGrub(CiTestCase): | |||
1979 | 721 | } | 770 | } |
1980 | 722 | } | 771 | } |
1981 | 723 | self.mock_haspkg.return_value = False | 772 | self.mock_haspkg.return_value = False |
1983 | 724 | curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family) | 773 | curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family, |
1984 | 774 | variant=self.variant) | ||
1985 | 725 | 775 | ||
1986 | 726 | expected_calls = [ | 776 | expected_calls = [ |
1987 | 727 | call(['efibootmgr', '-B', '-b', '0001'], | 777 | call(['efibootmgr', '-B', '-b', '0001'], |
1988 | @@ -762,70 +812,304 @@ class TestSetupGrub(CiTestCase): | |||
1989 | 762 | } | 812 | } |
1990 | 763 | } | 813 | } |
1991 | 764 | self.mock_haspkg.return_value = False | 814 | self.mock_haspkg.return_value = False |
1993 | 765 | curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family) | 815 | curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family, |
1994 | 816 | variant=self.variant) | ||
1995 | 766 | self.assertEquals([ | 817 | self.assertEquals([ |
1996 | 767 | call(['efibootmgr', '-o', '0001,0000'], target=self.target)], | 818 | call(['efibootmgr', '-o', '0001,0000'], target=self.target)], |
1997 | 768 | self.mock_subp.call_args_list) | 819 | self.mock_subp.call_args_list) |
1998 | 769 | 820 | ||
1999 | 821 | @patch.object(util.ChrootableTarget, "__enter__", new=lambda a: a) | ||
2000 | 822 | def test_grub_install_uefi_reorders_no_current_new_entry(self): | ||
2001 | 823 | self.add_patch('curtin.distro.install_packages', 'mock_install') | ||
2002 | 824 | self.add_patch('curtin.distro.has_pkg_available', 'mock_haspkg') | ||
2003 | 825 | self.add_patch('curtin.util.get_efibootmgr', 'mock_efibootmgr') | ||
2004 | 826 | self.mock_is_uefi_bootable.return_value = True | ||
2005 | 827 | cfg = { | ||
2006 | 828 | 'grub': { | ||
2007 | 829 | 'install_devices': ['/dev/vdb'], | ||
2008 | 830 | 'update_nvram': True, | ||
2009 | 831 | 'remove_old_uefi_loaders': False, | ||
2010 | 832 | 'reorder_uefi': True, | ||
2011 | 833 | }, | ||
2012 | 834 | } | ||
2013 | 835 | |||
2014 | 836 | # Single existing entry 0001 | ||
2015 | 837 | efi_orig = EfiOutput() | ||
2016 | 838 | efi_orig.add_entry(bootnum='0001', name='centos') | ||
2017 | 770 | 839 | ||
2019 | 771 | class TestUefiRemoveDuplicateEntries(CiTestCase): | 840 | # After install add a second entry, 0000 to the front of order |
2020 | 841 | efi_post = copy.deepcopy(efi_orig) | ||
2021 | 842 | efi_post.add_entry(bootnum='0000', name='ubuntu') | ||
2022 | 843 | efi_post.set_order(['0000', '0001']) | ||
2023 | 772 | 844 | ||
2029 | 773 | def setUp(self): | 845 | # After reorder we should have the target install first |
2030 | 774 | super(TestUefiRemoveDuplicateEntries, self).setUp() | 846 | efi_final = copy.deepcopy(efi_post) |
2031 | 775 | self.target = self.tmp_dir() | 847 | |
2032 | 776 | self.add_patch('curtin.util.get_efibootmgr', 'm_efibootmgr') | 848 | self.mock_efibootmgr.side_effect = iter([ |
2033 | 777 | self.add_patch('curtin.util.subp', 'm_subp') | 849 | efi_orig.as_dict(), # collect original order before install |
2034 | 850 | efi_orig.as_dict(), # remove_old_loaders query (no change) | ||
2035 | 851 | efi_post.as_dict(), # efi table after grub install, (changed) | ||
2036 | 852 | efi_final.as_dict(), # remove duplicates checks and finds reorder | ||
2037 | 853 | # has changed | ||
2038 | 854 | ]) | ||
2039 | 855 | self.mock_haspkg.return_value = False | ||
2040 | 856 | curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family, | ||
2041 | 857 | variant=self.variant) | ||
2042 | 858 | logs = self.logs.getvalue() | ||
2043 | 859 | print(logs) | ||
2044 | 860 | self.assertEquals([], self.mock_subp.call_args_list) | ||
2045 | 861 | self.assertIn("Using fallback UEFI reordering:", logs) | ||
2046 | 862 | self.assertIn("missing 'BootCurrent' value", logs) | ||
2047 | 863 | self.assertIn("Found new boot entries: ['0000']", logs) | ||
2048 | 778 | 864 | ||
2049 | 779 | @patch.object(util.ChrootableTarget, "__enter__", new=lambda a: a) | 865 | @patch.object(util.ChrootableTarget, "__enter__", new=lambda a: a) |
2051 | 780 | def test_uefi_remove_duplicate_entries(self): | 866 | def test_grub_install_uefi_reorders_no_curr_same_size_order_no_match(self): |
2052 | 867 | self.add_patch('curtin.distro.install_packages', 'mock_install') | ||
2053 | 868 | self.add_patch('curtin.distro.has_pkg_available', 'mock_haspkg') | ||
2054 | 869 | self.add_patch('curtin.util.get_efibootmgr', 'mock_efibootmgr') | ||
2055 | 870 | self.add_patch('curtin.commands.curthooks.uefi_remove_old_loaders', | ||
2056 | 871 | 'mock_remove_old_loaders') | ||
2057 | 872 | self.mock_is_uefi_bootable.return_value = True | ||
2058 | 781 | cfg = { | 873 | cfg = { |
2059 | 782 | 'grub': { | 874 | 'grub': { |
2060 | 783 | 'install_devices': ['/dev/vdb'], | 875 | 'install_devices': ['/dev/vdb'], |
2061 | 784 | 'update_nvram': True, | 876 | 'update_nvram': True, |
2062 | 877 | 'remove_old_uefi_loaders': False, | ||
2063 | 878 | 'reorder_uefi': True, | ||
2064 | 785 | }, | 879 | }, |
2065 | 786 | } | 880 | } |
2090 | 787 | self.m_efibootmgr.return_value = { | 881 | |
2091 | 788 | 'current': '0000', | 882 | # Existing Custom Ubuntu, usb and cd/dvd entry, booting Ubuntu |
2092 | 789 | 'entries': { | 883 | efi_orig = EfiOutput() |
2093 | 790 | '0000': { | 884 | efi_orig.add_entry(bootnum='0001', name='Ubuntu Deluxe Edition') |
2094 | 791 | 'name': 'ubuntu', | 885 | efi_orig.add_entry(bootnum='0002', name='USB Device') |
2095 | 792 | 'path': ( | 886 | efi_orig.add_entry(bootnum='0000', name='CD/DVD') |
2096 | 793 | 'HD(1,GPT)/File(\\EFI\\ubuntu\\shimx64.efi)'), | 887 | efi_orig.set_order(['0001', '0002', '0000']) |
2097 | 794 | }, | 888 | |
2098 | 795 | '0001': { | 889 | # after install existing ubuntu entry is reused, no change in order |
2099 | 796 | 'name': 'ubuntu', | 890 | efi_post = efi_orig |
2100 | 797 | 'path': ( | 891 | |
2101 | 798 | 'HD(1,GPT)/File(\\EFI\\ubuntu\\shimx64.efi)'), | 892 | # after reorder, no change is made due to the installed distro variant |
2102 | 799 | }, | 893 | # string 'ubuntu' is not found in the boot entries so we retain the |
2103 | 800 | '0002': { # Is not a duplicate because of unique path | 894 | # original efi order. |
2104 | 801 | 'name': 'ubuntu', | 895 | efi_final = efi_post |
2105 | 802 | 'path': ( | 896 | |
2106 | 803 | 'HD(2,GPT)/File(\\EFI\\ubuntu\\shimx64.efi)'), | 897 | self.mock_efibootmgr.side_effect = iter([ |
2107 | 804 | }, | 898 | efi_orig.as_dict(), # collect original order before install |
2108 | 805 | '0003': { # Is duplicate of 0000 | 899 | efi_orig.as_dict(), # remove_old_loaders query |
2109 | 806 | 'name': 'ubuntu', | 900 | efi_post.as_dict(), # reorder entries queries post install |
2110 | 807 | 'path': ( | 901 | efi_final.as_dict(), # remove duplicates checks and finds reorder |
2111 | 808 | 'HD(1,GPT)/File(\\EFI\\ubuntu\\shimx64.efi)'), | 902 | ]) |
2112 | 809 | }, | 903 | |
2113 | 810 | } | 904 | self.mock_haspkg.return_value = False |
2114 | 905 | curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family, | ||
2115 | 906 | variant=self.variant) | ||
2116 | 907 | |||
2117 | 908 | logs = self.logs.getvalue() | ||
2118 | 909 | print(logs) | ||
2119 | 910 | self.assertEquals([], self.mock_subp.call_args_list) | ||
2120 | 911 | self.assertIn("Using fallback UEFI reordering:", logs) | ||
2121 | 912 | self.assertIn("missing 'BootCurrent' value", logs) | ||
2122 | 913 | self.assertIn("Current and Previous bootorders match", logs) | ||
2123 | 914 | self.assertIn("Looking for installed entry variant=", logs) | ||
2124 | 915 | self.assertIn("Did not find an entry with variant=", logs) | ||
2125 | 916 | self.assertIn("No changes to boot order.", logs) | ||
2126 | 917 | |||
2127 | 918 | @patch.object(util.ChrootableTarget, "__enter__", new=lambda a: a) | ||
2128 | 919 | def test_grub_install_uefi_reorders_force_fallback(self): | ||
2129 | 920 | self.add_patch('curtin.distro.install_packages', 'mock_install') | ||
2130 | 921 | self.add_patch('curtin.distro.has_pkg_available', 'mock_haspkg') | ||
2131 | 922 | self.add_patch('curtin.util.get_efibootmgr', 'mock_efibootmgr') | ||
2132 | 923 | self.mock_is_uefi_bootable.return_value = True | ||
2133 | 924 | cfg = { | ||
2134 | 925 | 'grub': { | ||
2135 | 926 | 'install_devices': ['/dev/vdb'], | ||
2136 | 927 | 'update_nvram': True, | ||
2137 | 928 | 'remove_old_uefi_loaders': True, | ||
2138 | 929 | 'reorder_uefi': True, | ||
2139 | 930 | 'reorder_uefi_force_fallback': True, | ||
2140 | 931 | }, | ||
2141 | 811 | } | 932 | } |
2142 | 933 | # Single existing entry 0001 and set as current, which should avoid | ||
2143 | 934 | # any fallback logic, but we're forcing fallback pack via config | ||
2144 | 935 | efi_orig = EfiOutput() | ||
2145 | 936 | efi_orig.add_entry(bootnum='0001', name='PXE', current=True) | ||
2146 | 937 | print(efi_orig.as_dict()) | ||
2147 | 938 | |||
2148 | 939 | # After install add a second entry, 0000 to the front of order | ||
2149 | 940 | efi_post = copy.deepcopy(efi_orig) | ||
2150 | 941 | efi_post.add_entry(bootnum='0000', name='ubuntu') | ||
2151 | 942 | efi_post.set_order(['0000', '0001']) | ||
2152 | 943 | print(efi_orig.as_dict()) | ||
2153 | 944 | |||
2154 | 945 | # After reorder we should have the original boot entry 0001 as first | ||
2155 | 946 | efi_final = copy.deepcopy(efi_post) | ||
2156 | 947 | efi_final.set_order(['0001', '0000']) | ||
2157 | 948 | |||
2158 | 949 | self.mock_efibootmgr.side_effect = iter([ | ||
2159 | 950 | efi_orig.as_dict(), # collect original order before install | ||
2160 | 951 | efi_orig.as_dict(), # remove_old_loaders query (no change) | ||
2161 | 952 | efi_post.as_dict(), # efi table after grub install, (changed) | ||
2162 | 953 | efi_final.as_dict(), # remove duplicates checks and finds reorder | ||
2163 | 954 | # has changed | ||
2164 | 955 | ]) | ||
2165 | 812 | 956 | ||
2167 | 813 | curthooks.uefi_remove_duplicate_entries(cfg, self.target) | 957 | self.mock_haspkg.return_value = False |
2168 | 958 | curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family, | ||
2169 | 959 | variant=self.variant) | ||
2170 | 960 | logs = self.logs.getvalue() | ||
2171 | 961 | print(logs) | ||
2172 | 814 | self.assertEquals([ | 962 | self.assertEquals([ |
2178 | 815 | call(['efibootmgr', '--bootnum=0001', '--delete-bootnum'], | 963 | call(['efibootmgr', '-o', '0001,0000'], target=self.target)], |
2179 | 816 | target=self.target), | 964 | self.mock_subp.call_args_list) |
2180 | 817 | call(['efibootmgr', '--bootnum=0003', '--delete-bootnum'], | 965 | self.assertIn("Using fallback UEFI reordering:", logs) |
2181 | 818 | target=self.target) | 966 | self.assertIn("config 'reorder_uefi_force_fallback' is True", logs) |
2177 | 819 | ], self.m_subp.call_args_list) | ||
2182 | 820 | 967 | ||
2183 | 821 | @patch.object(util.ChrootableTarget, "__enter__", new=lambda a: a) | 968 | @patch.object(util.ChrootableTarget, "__enter__", new=lambda a: a) |
2185 | 822 | def test_uefi_remove_duplicate_entries_no_change(self): | 969 | def test_grub_install_uefi_reorders_network_first(self): |
2186 | 970 | self.add_patch('curtin.distro.install_packages', 'mock_install') | ||
2187 | 971 | self.add_patch('curtin.distro.has_pkg_available', 'mock_haspkg') | ||
2188 | 972 | self.add_patch('curtin.util.get_efibootmgr', 'mock_efibootmgr') | ||
2189 | 973 | self.mock_is_uefi_bootable.return_value = True | ||
2190 | 823 | cfg = { | 974 | cfg = { |
2191 | 824 | 'grub': { | 975 | 'grub': { |
2192 | 825 | 'install_devices': ['/dev/vdb'], | 976 | 'install_devices': ['/dev/vdb'], |
2193 | 826 | 'update_nvram': True, | 977 | 'update_nvram': True, |
2194 | 978 | 'remove_old_uefi_loaders': True, | ||
2195 | 979 | 'reorder_uefi': True, | ||
2196 | 980 | }, | ||
2197 | 981 | } | ||
2198 | 982 | |||
2199 | 983 | # Existing ubuntu, usb and cd/dvd entry, booting ubuntu | ||
2200 | 984 | efi_orig = EfiOutput() | ||
2201 | 985 | efi_orig.add_entry(bootnum='0001', name='centos') | ||
2202 | 986 | efi_orig.add_entry(bootnum='0002', name='Network') | ||
2203 | 987 | efi_orig.add_entry(bootnum='0003', name='PXE') | ||
2204 | 988 | efi_orig.add_entry(bootnum='0004', name='LAN') | ||
2205 | 989 | efi_orig.add_entry(bootnum='0000', name='CD/DVD') | ||
2206 | 990 | efi_orig.set_order(['0001', '0002', '0003', '0004', '0000']) | ||
2207 | 991 | print(efi_orig.as_dict()) | ||
2208 | 992 | |||
2209 | 993 | # after install we add an ubuntu entry, and grub puts it first | ||
2210 | 994 | efi_post = copy.deepcopy(efi_orig) | ||
2211 | 995 | efi_post.add_entry(bootnum='0007', name='ubuntu') | ||
2212 | 996 | efi_post.set_order(['0007'] + efi_orig.order) | ||
2213 | 997 | print(efi_post.as_dict()) | ||
2214 | 998 | |||
2215 | 999 | # reorder must place all network devices first, then ubuntu, and others | ||
2216 | 1000 | efi_final = copy.deepcopy(efi_post) | ||
2217 | 1001 | expected_order = ['0002', '0003', '0004', '0007', '0001', '0000'] | ||
2218 | 1002 | efi_final.set_order(expected_order) | ||
2219 | 1003 | |||
2220 | 1004 | self.mock_efibootmgr.side_effect = iter([ | ||
2221 | 1005 | efi_orig.as_dict(), # collect original order before install | ||
2222 | 1006 | efi_orig.as_dict(), # remove_old_loaders query | ||
2223 | 1007 | efi_post.as_dict(), # reorder entries queries post install | ||
2224 | 1008 | efi_final.as_dict(), # remove duplicates checks and finds reorder | ||
2225 | 1009 | ]) | ||
2226 | 1010 | self.mock_haspkg.return_value = False | ||
2227 | 1011 | curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family, | ||
2228 | 1012 | variant=self.variant) | ||
2229 | 1013 | logs = self.logs.getvalue() | ||
2230 | 1014 | print(logs) | ||
2231 | 1015 | print('Number of bootmgr calls: %s' % self.mock_efibootmgr.call_count) | ||
2232 | 1016 | self.assertEquals([ | ||
2233 | 1017 | call(['efibootmgr', '-o', '%s' % (",".join(expected_order))], | ||
2234 | 1018 | target=self.target)], | ||
2235 | 1019 | self.mock_subp.call_args_list) | ||
2236 | 1020 | self.assertIn("Using fallback UEFI reordering:", logs) | ||
2237 | 1021 | self.assertIn("missing 'BootCurrent' value", logs) | ||
2238 | 1022 | self.assertIn("Looking for installed entry variant=", logs) | ||
2239 | 1023 | self.assertIn("found netboot entries: ['0002', '0003', '0004']", logs) | ||
2240 | 1024 | self.assertIn("found other entries: ['0001', '0000']", logs) | ||
2241 | 1025 | self.assertIn("found target entry: ['0007']", logs) | ||
2242 | 1026 | |||
2243 | 1027 | |||
2244 | 1028 | class TestUefiRemoveDuplicateEntries(CiTestCase): | ||
2245 | 1029 | |||
2246 | 1030 | efibootmgr_output = { | ||
2247 | 1031 | 'current': '0000', | ||
2248 | 1032 | 'entries': { | ||
2249 | 1033 | '0000': { | ||
2250 | 1034 | 'name': 'ubuntu', | ||
2251 | 1035 | 'path': ( | ||
2252 | 1036 | 'HD(1,GPT)/File(\\EFI\\ubuntu\\shimx64.efi)'), | ||
2253 | 1037 | }, | ||
2254 | 1038 | '0001': { # Is duplicate of 0000 | ||
2255 | 1039 | 'name': 'ubuntu', | ||
2256 | 1040 | 'path': ( | ||
2257 | 1041 | 'HD(1,GPT)/File(\\EFI\\ubuntu\\shimx64.efi)'), | ||
2258 | 1042 | }, | ||
2259 | 1043 | '0002': { # Is not a duplicate because of unique path | ||
2260 | 1044 | 'name': 'ubuntu', | ||
2261 | 1045 | 'path': ( | ||
2262 | 1046 | 'HD(2,GPT)/File(\\EFI\\ubuntu\\shimx64.efi)'), | ||
2263 | 1047 | }, | ||
2264 | 1048 | '0003': { # Is duplicate of 0000 | ||
2265 | 1049 | 'name': 'ubuntu', | ||
2266 | 1050 | 'path': ( | ||
2267 | 1051 | 'HD(1,GPT)/File(\\EFI\\ubuntu\\shimx64.efi)'), | ||
2268 | 827 | }, | 1052 | }, |
2269 | 828 | } | 1053 | } |
2270 | 1054 | } | ||
2271 | 1055 | |||
2272 | 1056 | def setUp(self): | ||
2273 | 1057 | super(TestUefiRemoveDuplicateEntries, self).setUp() | ||
2274 | 1058 | self.target = self.tmp_dir() | ||
2275 | 1059 | self.add_patch('curtin.util.get_efibootmgr', 'm_efibootmgr') | ||
2276 | 1060 | self.add_patch('curtin.util.subp', 'm_subp') | ||
2277 | 1061 | self.m_efibootmgr.return_value = copy.deepcopy(self.efibootmgr_output) | ||
2278 | 1062 | |||
2279 | 1063 | @patch.object(util.ChrootableTarget, "__enter__", new=lambda a: a) | ||
2280 | 1064 | def test_uefi_remove_duplicate_entries(self): | ||
2281 | 1065 | grubcfg = {} | ||
2282 | 1066 | curthooks.uefi_remove_duplicate_entries(grubcfg, self.target) | ||
2283 | 1067 | self.assertEquals([ | ||
2284 | 1068 | call(['efibootmgr', '--bootnum=0001', '--delete-bootnum'], | ||
2285 | 1069 | target=self.target), | ||
2286 | 1070 | call(['efibootmgr', '--bootnum=0003', '--delete-bootnum'], | ||
2287 | 1071 | target=self.target) | ||
2288 | 1072 | ], self.m_subp.call_args_list) | ||
2289 | 1073 | |||
2290 | 1074 | @patch.object(util.ChrootableTarget, "__enter__", new=lambda a: a) | ||
2291 | 1075 | def test_uefi_remove_duplicate_entries_no_bootcurrent(self): | ||
2292 | 1076 | grubcfg = {} | ||
2293 | 1077 | efiout = copy.deepcopy(self.efibootmgr_output) | ||
2294 | 1078 | del efiout['current'] | ||
2295 | 1079 | self.m_efibootmgr.return_value = efiout | ||
2296 | 1080 | curthooks.uefi_remove_duplicate_entries(grubcfg, self.target) | ||
2297 | 1081 | self.assertEquals([ | ||
2298 | 1082 | call(['efibootmgr', '--bootnum=0001', '--delete-bootnum'], | ||
2299 | 1083 | target=self.target), | ||
2300 | 1084 | call(['efibootmgr', '--bootnum=0003', '--delete-bootnum'], | ||
2301 | 1085 | target=self.target) | ||
2302 | 1086 | ], self.m_subp.call_args_list) | ||
2303 | 1087 | |||
2304 | 1088 | @patch.object(util.ChrootableTarget, "__enter__", new=lambda a: a) | ||
2305 | 1089 | def test_uefi_remove_duplicate_entries_disabled(self): | ||
2306 | 1090 | grubcfg = { | ||
2307 | 1091 | 'remove_duplicate_entries': False, | ||
2308 | 1092 | } | ||
2309 | 1093 | curthooks.uefi_remove_duplicate_entries(grubcfg, self.target) | ||
2310 | 1094 | self.assertEquals([], self.m_subp.call_args_list) | ||
2311 | 1095 | |||
2312 | 1096 | @patch.object(util.ChrootableTarget, "__enter__", new=lambda a: a) | ||
2313 | 1097 | def test_uefi_remove_duplicate_entries_skip_bootcurrent(self): | ||
2314 | 1098 | grubcfg = {} | ||
2315 | 1099 | efiout = copy.deepcopy(self.efibootmgr_output) | ||
2316 | 1100 | efiout['current'] = '0003' | ||
2317 | 1101 | self.m_efibootmgr.return_value = efiout | ||
2318 | 1102 | curthooks.uefi_remove_duplicate_entries(grubcfg, self.target) | ||
2319 | 1103 | self.assertEquals([ | ||
2320 | 1104 | call(['efibootmgr', '--bootnum=0000', '--delete-bootnum'], | ||
2321 | 1105 | target=self.target), | ||
2322 | 1106 | call(['efibootmgr', '--bootnum=0001', '--delete-bootnum'], | ||
2323 | 1107 | target=self.target), | ||
2324 | 1108 | ], self.m_subp.call_args_list) | ||
2325 | 1109 | |||
2326 | 1110 | @patch.object(util.ChrootableTarget, "__enter__", new=lambda a: a) | ||
2327 | 1111 | def test_uefi_remove_duplicate_entries_no_change(self): | ||
2328 | 1112 | grubcfg = {} | ||
2329 | 829 | self.m_efibootmgr.return_value = { | 1113 | self.m_efibootmgr.return_value = { |
2330 | 830 | 'current': '0000', | 1114 | 'current': '0000', |
2331 | 831 | 'entries': { | 1115 | 'entries': { |
2332 | @@ -846,8 +1130,7 @@ class TestUefiRemoveDuplicateEntries(CiTestCase): | |||
2333 | 846 | }, | 1130 | }, |
2334 | 847 | } | 1131 | } |
2335 | 848 | } | 1132 | } |
2338 | 849 | 1133 | curthooks.uefi_remove_duplicate_entries(grubcfg, self.target) | |
2337 | 850 | curthooks.uefi_remove_duplicate_entries(cfg, self.target) | ||
2339 | 851 | self.assertEquals([], self.m_subp.call_args_list) | 1134 | self.assertEquals([], self.m_subp.call_args_list) |
2340 | 852 | 1135 | ||
2341 | 853 | 1136 | ||
2342 | @@ -1110,9 +1393,8 @@ class TestDetectRequiredPackages(CiTestCase): | |||
2343 | 1110 | {'type': 'static', 'address': '2001:1::1/64'}]}}, | 1393 | {'type': 'static', 'address': '2001:1::1/64'}]}}, |
2344 | 1111 | 2: { | 1394 | 2: { |
2345 | 1112 | 'openvswitch': { | 1395 | 'openvswitch': { |
2349 | 1113 | 'openvswitch': { | 1396 | 'bridges': { |
2350 | 1114 | 'bridges': { | 1397 | 'br-int': {'openvswitch': {}}}}, |
2348 | 1115 | 'br-int': {'ports': {'eth15': {'tag': 2}}}}}}, | ||
2351 | 1116 | 'vlans': { | 1398 | 'vlans': { |
2352 | 1117 | 'vlans': { | 1399 | 'vlans': { |
2353 | 1118 | 'en-intra': {'id': 1, 'link': 'eno1', 'dhcp4': 'yes'}, | 1400 | 'en-intra': {'id': 1, 'link': 'eno1', 'dhcp4': 'yes'}, |
2354 | @@ -1245,7 +1527,7 @@ class TestDetectRequiredPackages(CiTestCase): | |||
2355 | 1245 | ({'network': { | 1527 | ({'network': { |
2356 | 1246 | 'version': 2, | 1528 | 'version': 2, |
2357 | 1247 | 'items': ('openvswitch',)}}, | 1529 | 'items': ('openvswitch',)}}, |
2359 | 1248 | ('openvswitch-switch', )), | 1530 | ('bridge-utils', 'openvswitch-switch', )), |
2360 | 1249 | )) | 1531 | )) |
2361 | 1250 | 1532 | ||
2362 | 1251 | def test_network_v2_detect_renderers(self): | 1533 | def test_network_v2_detect_renderers(self): |
2363 | @@ -1726,6 +2008,12 @@ class TestUefiFindGrubDeviceIds(CiTestCase): | |||
2364 | 1726 | 'fstype': 'fat32', | 2008 | 'fstype': 'fat32', |
2365 | 1727 | }, | 2009 | }, |
2366 | 1728 | { | 2010 | { |
2367 | 2011 | 'id': 'vdb-part2-swap_mount', | ||
2368 | 2012 | 'type': 'mount', | ||
2369 | 2013 | 'device': 'vdb-part2-swap_format', | ||
2370 | 2014 | 'options': '', | ||
2371 | 2015 | }, | ||
2372 | 2016 | { | ||
2373 | 1729 | 'id': 'vdb-part1_mount', | 2017 | 'id': 'vdb-part1_mount', |
2374 | 1730 | 'type': 'mount', | 2018 | 'type': 'mount', |
2375 | 1731 | 'device': 'vdb-part1_format', | 2019 | 'device': 'vdb-part1_format', |
2376 | diff --git a/tests/unittests/test_distro.py b/tests/unittests/test_distro.py | |||
2377 | index eb62dd8..380680c 100644 | |||
2378 | --- a/tests/unittests/test_distro.py | |||
2379 | +++ b/tests/unittests/test_distro.py | |||
2380 | @@ -65,7 +65,7 @@ class TestParseDpkgVersion(CiTestCase): | |||
2381 | 65 | def test_simple_native_package_version(self): | 65 | def test_simple_native_package_version(self): |
2382 | 66 | """dpkg versions must have a -. If not present expect value error.""" | 66 | """dpkg versions must have a -. If not present expect value error.""" |
2383 | 67 | self.assertEqual( | 67 | self.assertEqual( |
2385 | 68 | {'major': 2, 'minor': 28, 'micro': 0, 'extra': None, | 68 | {'epoch': 0, 'major': 2, 'minor': 28, 'micro': 0, 'extra': None, |
2386 | 69 | 'raw': '2.28', 'upstream': '2.28', 'name': 'germinate', | 69 | 'raw': '2.28', 'upstream': '2.28', 'name': 'germinate', |
2387 | 70 | 'semantic_version': 22800}, | 70 | 'semantic_version': 22800}, |
2388 | 71 | distro.parse_dpkg_version('2.28', name='germinate')) | 71 | distro.parse_dpkg_version('2.28', name='germinate')) |
2389 | @@ -73,7 +73,7 @@ class TestParseDpkgVersion(CiTestCase): | |||
2390 | 73 | def test_complex_native_package_version(self): | 73 | def test_complex_native_package_version(self): |
2391 | 74 | dver = '1.0.106ubuntu2+really1.0.97ubuntu1' | 74 | dver = '1.0.106ubuntu2+really1.0.97ubuntu1' |
2392 | 75 | self.assertEqual( | 75 | self.assertEqual( |
2394 | 76 | {'major': 1, 'minor': 0, 'micro': 106, | 76 | {'epoch': 0, 'major': 1, 'minor': 0, 'micro': 106, |
2395 | 77 | 'extra': 'ubuntu2+really1.0.97ubuntu1', | 77 | 'extra': 'ubuntu2+really1.0.97ubuntu1', |
2396 | 78 | 'raw': dver, 'upstream': dver, 'name': 'debootstrap', | 78 | 'raw': dver, 'upstream': dver, 'name': 'debootstrap', |
2397 | 79 | 'semantic_version': 100106}, | 79 | 'semantic_version': 100106}, |
2398 | @@ -82,14 +82,14 @@ class TestParseDpkgVersion(CiTestCase): | |||
2399 | 82 | 82 | ||
2400 | 83 | def test_simple_valid(self): | 83 | def test_simple_valid(self): |
2401 | 84 | self.assertEqual( | 84 | self.assertEqual( |
2403 | 85 | {'major': 1, 'minor': 2, 'micro': 3, 'extra': None, | 85 | {'epoch': 0, 'major': 1, 'minor': 2, 'micro': 3, 'extra': None, |
2404 | 86 | 'raw': '1.2.3-0', 'upstream': '1.2.3', 'name': 'foo', | 86 | 'raw': '1.2.3-0', 'upstream': '1.2.3', 'name': 'foo', |
2405 | 87 | 'semantic_version': 10203}, | 87 | 'semantic_version': 10203}, |
2406 | 88 | distro.parse_dpkg_version('1.2.3-0', name='foo')) | 88 | distro.parse_dpkg_version('1.2.3-0', name='foo')) |
2407 | 89 | 89 | ||
2408 | 90 | def test_simple_valid_with_semx(self): | 90 | def test_simple_valid_with_semx(self): |
2409 | 91 | self.assertEqual( | 91 | self.assertEqual( |
2411 | 92 | {'major': 1, 'minor': 2, 'micro': 3, 'extra': None, | 92 | {'epoch': 0, 'major': 1, 'minor': 2, 'micro': 3, 'extra': None, |
2412 | 93 | 'raw': '1.2.3-0', 'upstream': '1.2.3', | 93 | 'raw': '1.2.3-0', 'upstream': '1.2.3', |
2413 | 94 | 'semantic_version': 123}, | 94 | 'semantic_version': 123}, |
2414 | 95 | distro.parse_dpkg_version('1.2.3-0', semx=(100, 10, 1))) | 95 | distro.parse_dpkg_version('1.2.3-0', semx=(100, 10, 1))) |
2415 | @@ -98,7 +98,8 @@ class TestParseDpkgVersion(CiTestCase): | |||
2416 | 98 | """upstream versions may have a hyphen.""" | 98 | """upstream versions may have a hyphen.""" |
2417 | 99 | cver = '18.2-14-g6d48d265-0ubuntu1' | 99 | cver = '18.2-14-g6d48d265-0ubuntu1' |
2418 | 100 | self.assertEqual( | 100 | self.assertEqual( |
2420 | 101 | {'major': 18, 'minor': 2, 'micro': 0, 'extra': '-14-g6d48d265', | 101 | {'epoch': 0, 'major': 18, 'minor': 2, 'micro': 0, |
2421 | 102 | 'extra': '-14-g6d48d265', | ||
2422 | 102 | 'raw': cver, 'upstream': '18.2-14-g6d48d265', | 103 | 'raw': cver, 'upstream': '18.2-14-g6d48d265', |
2423 | 103 | 'name': 'cloud-init', 'semantic_version': 180200}, | 104 | 'name': 'cloud-init', 'semantic_version': 180200}, |
2424 | 104 | distro.parse_dpkg_version(cver, name='cloud-init')) | 105 | distro.parse_dpkg_version(cver, name='cloud-init')) |
2425 | @@ -107,11 +108,30 @@ class TestParseDpkgVersion(CiTestCase): | |||
2426 | 107 | """multipath tools has a + in it.""" | 108 | """multipath tools has a + in it.""" |
2427 | 108 | mver = '0.5.0+git1.656f8865-5ubuntu2.5' | 109 | mver = '0.5.0+git1.656f8865-5ubuntu2.5' |
2428 | 109 | self.assertEqual( | 110 | self.assertEqual( |
2430 | 110 | {'major': 0, 'minor': 5, 'micro': 0, 'extra': '+git1.656f8865', | 111 | {'epoch': 0, 'major': 0, 'minor': 5, 'micro': 0, |
2431 | 112 | 'extra': '+git1.656f8865', | ||
2432 | 111 | 'raw': mver, 'upstream': '0.5.0+git1.656f8865', | 113 | 'raw': mver, 'upstream': '0.5.0+git1.656f8865', |
2433 | 112 | 'semantic_version': 500}, | 114 | 'semantic_version': 500}, |
2434 | 113 | distro.parse_dpkg_version(mver)) | 115 | distro.parse_dpkg_version(mver)) |
2435 | 114 | 116 | ||
2436 | 117 | def test_package_with_epoch(self): | ||
2437 | 118 | """xxd has epoch""" | ||
2438 | 119 | mver = '2:8.1.2269-1ubuntu5' | ||
2439 | 120 | self.assertEqual( | ||
2440 | 121 | {'epoch': 2, 'major': 8, 'minor': 1, 'micro': 2269, | ||
2441 | 122 | 'extra': None, 'raw': mver, 'upstream': '8.1.2269', | ||
2442 | 123 | 'semantic_version': 82369}, | ||
2443 | 124 | distro.parse_dpkg_version(mver)) | ||
2444 | 125 | |||
2445 | 126 | def test_package_with_dot_in_extra(self): | ||
2446 | 127 | """linux-image-generic has multiple dots in extra""" | ||
2447 | 128 | mver = '5.4.0.37.40' | ||
2448 | 129 | self.assertEqual( | ||
2449 | 130 | {'epoch': 0, 'major': 5, 'minor': 4, 'micro': 0, | ||
2450 | 131 | 'extra': '37.40', 'raw': mver, 'upstream': '5.4.0.37.40', | ||
2451 | 132 | 'semantic_version': 50400}, | ||
2452 | 133 | distro.parse_dpkg_version(mver)) | ||
2453 | 134 | |||
2454 | 115 | 135 | ||
2455 | 116 | class TestDistros(CiTestCase): | 136 | class TestDistros(CiTestCase): |
2456 | 117 | 137 | ||
2457 | @@ -429,6 +449,7 @@ class TestSystemUpgrade(CiTestCase): | |||
2458 | 429 | auto_remove = apt_base + ['autoremove'] | 449 | auto_remove = apt_base + ['autoremove'] |
2459 | 430 | expected_calls = [ | 450 | expected_calls = [ |
2460 | 431 | mock.call(apt_cmd, env=env, target=paths.target_path(target)), | 451 | mock.call(apt_cmd, env=env, target=paths.target_path(target)), |
2461 | 452 | mock.call(['apt-get', 'clean'], target=paths.target_path(target)), | ||
2462 | 432 | mock.call(auto_remove, env=env, target=paths.target_path(target)), | 453 | mock.call(auto_remove, env=env, target=paths.target_path(target)), |
2463 | 433 | ] | 454 | ] |
2464 | 434 | which_calls = [mock.call('eatmydata', target=target)] | 455 | which_calls = [mock.call('eatmydata', target=target)] |
2465 | diff --git a/tests/unittests/test_feature.py b/tests/unittests/test_feature.py | |||
2466 | index 7c55882..8690ad8 100644 | |||
2467 | --- a/tests/unittests/test_feature.py | |||
2468 | +++ b/tests/unittests/test_feature.py | |||
2469 | @@ -24,4 +24,10 @@ class TestExportsFeatures(CiTestCase): | |||
2470 | 24 | def test_has_centos_curthook_support(self): | 24 | def test_has_centos_curthook_support(self): |
2471 | 25 | self.assertIn('CENTOS_CURTHOOK_SUPPORT', curtin.FEATURES) | 25 | self.assertIn('CENTOS_CURTHOOK_SUPPORT', curtin.FEATURES) |
2472 | 26 | 26 | ||
2473 | 27 | def test_has_btrfs_swapfile_support(self): | ||
2474 | 28 | self.assertIn('BTRFS_SWAPFILE', curtin.FEATURES) | ||
2475 | 29 | |||
2476 | 30 | def test_has_uefi_reorder_fallback_support(self): | ||
2477 | 31 | self.assertIn('UEFI_REORDER_FALLBACK_SUPPORT', curtin.FEATURES) | ||
2478 | 32 | |||
2479 | 27 | # vi: ts=4 expandtab syntax=python | 33 | # vi: ts=4 expandtab syntax=python |
2480 | diff --git a/tests/vmtests/__init__.py b/tests/vmtests/__init__.py | |||
2481 | index 32cd5fd..0b19d8f 100644 | |||
2482 | --- a/tests/vmtests/__init__.py | |||
2483 | +++ b/tests/vmtests/__init__.py | |||
2484 | @@ -633,6 +633,7 @@ class VMBaseClass(TestCase): | |||
2485 | 633 | 633 | ||
2486 | 634 | # these get set from base_vm_classes | 634 | # these get set from base_vm_classes |
2487 | 635 | release = None | 635 | release = None |
2488 | 636 | supported_releases = [] | ||
2489 | 636 | arch = None | 637 | arch = None |
2490 | 637 | target_arch = None | 638 | target_arch = None |
2491 | 638 | kflavor = None | 639 | kflavor = None |
2492 | @@ -855,6 +856,13 @@ class VMBaseClass(TestCase): | |||
2493 | 855 | return {'kernel': {'fallback-package': package}} | 856 | return {'kernel': {'fallback-package': package}} |
2494 | 856 | 857 | ||
2495 | 857 | @classmethod | 858 | @classmethod |
2496 | 859 | def is_unsupported_release(cls): | ||
2497 | 860 | # allow unsupported releases opt-in to avoid the skiptest | ||
2498 | 861 | if cls.release in cls.supported_releases: | ||
2499 | 862 | return False | ||
2500 | 863 | return is_unsupported_ubuntu(cls.release) | ||
2501 | 864 | |||
2502 | 865 | @classmethod | ||
2503 | 858 | def skip_by_date(cls, *args, **kwargs): | 866 | def skip_by_date(cls, *args, **kwargs): |
2504 | 859 | """skip_by_date wrapper. this way other modules do not have | 867 | """skip_by_date wrapper. this way other modules do not have |
2505 | 860 | to add an import of skip_by_date to start skipping.""" | 868 | to add an import of skip_by_date to start skipping.""" |
2506 | @@ -883,7 +891,7 @@ class VMBaseClass(TestCase): | |||
2507 | 883 | "Class %s does not have required attrs set: %s" % | 891 | "Class %s does not have required attrs set: %s" % |
2508 | 884 | (cls.__name__, missing)) | 892 | (cls.__name__, missing)) |
2509 | 885 | 893 | ||
2511 | 886 | if is_unsupported_ubuntu(cls.release): | 894 | if cls.is_unsupported_release(): |
2512 | 887 | raise SkipTest('"%s" is unsupported release.' % cls.release) | 895 | raise SkipTest('"%s" is unsupported release.' % cls.release) |
2513 | 888 | 896 | ||
2514 | 889 | # check if we should skip due to host arch | 897 | # check if we should skip due to host arch |
2515 | @@ -1372,8 +1380,10 @@ class VMBaseClass(TestCase): | |||
2516 | 1372 | 'serial=%s' % os.path.basename(cls.td.output_disk)) | 1380 | 'serial=%s' % os.path.basename(cls.td.output_disk)) |
2517 | 1373 | target_disks.extend([output_disk]) | 1381 | target_disks.extend([output_disk]) |
2518 | 1374 | 1382 | ||
2519 | 1383 | # centos requires a reboot after first boot to do selinux relabing | ||
2520 | 1384 | noreboot = ['--no-reboot'] if cls.target_distro != 'centos' else [] | ||
2521 | 1375 | # create xkvm cmd | 1385 | # create xkvm cmd |
2523 | 1376 | cmd = (["tools/xkvm", "-v", dowait, '--no-reboot'] + | 1386 | cmd = (["tools/xkvm", "-v", dowait] + noreboot + |
2524 | 1377 | uefi_flags + netdevs + | 1387 | uefi_flags + netdevs + |
2525 | 1378 | cls.mpath_diskargs(target_disks + extra_disks + nvme_disks) + | 1388 | cls.mpath_diskargs(target_disks + extra_disks + nvme_disks) + |
2526 | 1379 | ["--disk=file=%s,if=virtio,media=cdrom" % cls.td.seed_disk] + | 1389 | ["--disk=file=%s,if=virtio,media=cdrom" % cls.td.seed_disk] + |
2527 | @@ -1666,8 +1676,8 @@ class VMBaseClass(TestCase): | |||
2528 | 1666 | if spec in line: | 1676 | if spec in line: |
2529 | 1667 | fstab_entry = line | 1677 | fstab_entry = line |
2530 | 1668 | self.assertIsNotNone(fstab_entry) | 1678 | self.assertIsNotNone(fstab_entry) |
2533 | 1669 | self.assertEqual(mp, fstab_entry.split(' ')[1]) | 1679 | self.assertEqual(mp, fstab_entry.split()[1]) |
2534 | 1670 | self.assertEqual(fsopts, fstab_entry.split(' ')[3]) | 1680 | self.assertEqual(fsopts, fstab_entry.split()[3]) |
2535 | 1671 | found.append((spec, mp, fsopts)) | 1681 | found.append((spec, mp, fsopts)) |
2536 | 1672 | 1682 | ||
2537 | 1673 | self.assertEqual(sorted(expected), sorted(found)) | 1683 | self.assertEqual(sorted(expected), sorted(found)) |
2538 | @@ -1753,12 +1763,28 @@ class VMBaseClass(TestCase): | |||
2539 | 1753 | for line in ls_byid.split('\n') | 1763 | for line in ls_byid.split('\n') |
2540 | 1754 | if ("virtio-" + serial) in line.split() or | 1764 | if ("virtio-" + serial) in line.split() or |
2541 | 1755 | ("scsi-" + serial) in line.split() or | 1765 | ("scsi-" + serial) in line.split() or |
2543 | 1756 | ("wwn-" + serial) in line.split()] | 1766 | ("wwn-" + serial) in line.split() or |
2544 | 1767 | (serial) in line.split()] | ||
2545 | 1768 | print("Looking for serial %s in 'ls_al_byid' content\n%s" % (serial, | ||
2546 | 1769 | ls_byid)) | ||
2547 | 1757 | self.assertEqual(len(kname), 1) | 1770 | self.assertEqual(len(kname), 1) |
2548 | 1758 | kname = kname.pop() | 1771 | kname = kname.pop() |
2549 | 1759 | self.assertIsNotNone(kname) | 1772 | self.assertIsNotNone(kname) |
2550 | 1760 | return kname | 1773 | return kname |
2551 | 1761 | 1774 | ||
2552 | 1775 | def _mdname_to_kname(self, mdname): | ||
2553 | 1776 | # extract kname from /dev/md/ on /dev/<kname> | ||
2554 | 1777 | # parsing ls -al output on /dev/md/*: | ||
2555 | 1778 | # lrwxrwxrwx 1 root root 8 May 28 16:26 /dev/md/os-raid1 -> ../md127 | ||
2556 | 1779 | ls_dev_md = self.load_collect_file("ls_al_dev_md") | ||
2557 | 1780 | knames = [os.path.basename(line.split()[-1]) | ||
2558 | 1781 | for line in ls_dev_md.split('\n') | ||
2559 | 1782 | if mdname in line] | ||
2560 | 1783 | self.assertEqual(len(knames), 1) | ||
2561 | 1784 | kname = knames.pop() | ||
2562 | 1785 | self.assertIsNotNone(kname) | ||
2563 | 1786 | return kname | ||
2564 | 1787 | |||
2565 | 1762 | def _kname_to_bypath(self, kname): | 1788 | def _kname_to_bypath(self, kname): |
2566 | 1763 | # extract path from /dev/disk/by-path on /dev/<kname> | 1789 | # extract path from /dev/disk/by-path on /dev/<kname> |
2567 | 1764 | # parsing ls -al output on /dev/disk/by-path | 1790 | # parsing ls -al output on /dev/disk/by-path |
2568 | @@ -1787,6 +1813,36 @@ class VMBaseClass(TestCase): | |||
2569 | 1787 | self.assertEqual(len(uuid), 36) | 1813 | self.assertEqual(len(uuid), 36) |
2570 | 1788 | return uuid | 1814 | return uuid |
2571 | 1789 | 1815 | ||
2572 | 1816 | def _byuuid_to_kname(self, devpath): | ||
2573 | 1817 | # lookup kname via /dev/disk/by-uuid symlink | ||
2574 | 1818 | # parsing ls -al output on /dev/disk/by-uuid: | ||
2575 | 1819 | # lrwxrwxrwx 1 root root 9 Dec 4 20:02 | ||
2576 | 1820 | # d591e9e9-825a-4f0a-b280-3bfaf470b83c -> ../../vdg | ||
2577 | 1821 | uuid = os.path.basename(devpath) | ||
2578 | 1822 | self.assertIsNotNone(uuid) | ||
2579 | 1823 | print(uuid) | ||
2580 | 1824 | ls_uuid = self.load_collect_file("ls_al_byuuid") | ||
2581 | 1825 | kname = [line.split()[-1] for line in ls_uuid.split('\n') | ||
2582 | 1826 | if uuid in line.split()] | ||
2583 | 1827 | self.assertEqual(len(kname), 1) | ||
2584 | 1828 | kname = os.path.basename(kname.pop()) | ||
2585 | 1829 | return kname | ||
2586 | 1830 | |||
2587 | 1831 | def _bypath_to_kname(self, devpath): | ||
2588 | 1832 | # lookup kname via /dev/disk/by-path symlink | ||
2589 | 1833 | # parsing ls -al output on /dev/disk/by-path: | ||
2590 | 1834 | # lrwxrwxrwx 1 root root 9 Dec 4 20:02 | ||
2591 | 1835 | # pci-0000:00:03.0-scsi-0:0:0:0-part3 -> ../../sda3 | ||
2592 | 1836 | dpath = os.path.basename(devpath) | ||
2593 | 1837 | self.assertIsNotNone(dpath) | ||
2594 | 1838 | print(dpath) | ||
2595 | 1839 | ls_bypath = self.load_collect_file("ls_al_bypath") | ||
2596 | 1840 | kname = [line.split()[-1] for line in ls_bypath.split('\n') | ||
2597 | 1841 | if dpath in line.split()] | ||
2598 | 1842 | self.assertEqual(len(kname), 1) | ||
2599 | 1843 | kname = os.path.basename(kname.pop()) | ||
2600 | 1844 | return kname | ||
2601 | 1845 | |||
2602 | 1790 | def _bcache_to_byuuid(self, kname): | 1846 | def _bcache_to_byuuid(self, kname): |
2603 | 1791 | # extract bcache uuid from /dev/bcache/by-uuid on /dev/<kname> | 1847 | # extract bcache uuid from /dev/bcache/by-uuid on /dev/<kname> |
2604 | 1792 | # parsing ls -al output on /dev/bcache/by-uuid | 1848 | # parsing ls -al output on /dev/bcache/by-uuid |
2605 | @@ -1968,25 +2024,44 @@ class VMBaseClass(TestCase): | |||
2606 | 1968 | 2024 | ||
2607 | 1969 | @skip_if_flag('expected_failure') | 2025 | @skip_if_flag('expected_failure') |
2608 | 1970 | def test_swaps_used(self): | 2026 | def test_swaps_used(self): |
2609 | 1971 | if not self.has_storage_config(): | ||
2610 | 1972 | raise SkipTest("This test does not use storage config.") | ||
2611 | 1973 | 2027 | ||
2617 | 1974 | stgcfg = self.get_storage_config() | 2028 | def find_fstab_swaps(): |
2618 | 1975 | swap_ids = [d["id"] for d in stgcfg if d.get("fstype") == "swap"] | 2029 | swaps = [] |
2619 | 1976 | swap_mounts = [d for d in stgcfg if d.get("device") in swap_ids] | 2030 | path = self.collect_path("fstab") |
2620 | 1977 | self.assertEqual(len(swap_ids), len(swap_mounts), | 2031 | if not os.path.exists(path): |
2621 | 1978 | "number config swap fstypes != number swap mounts") | 2032 | return swaps |
2622 | 2033 | for line in util.load_file(path).splitlines(): | ||
2623 | 2034 | if line.startswith("#"): | ||
2624 | 2035 | continue | ||
2625 | 2036 | (fs, mp, fstype, opts, dump, passno) = line.split() | ||
2626 | 2037 | if fstype == 'swap': | ||
2627 | 2038 | if fs.startswith('/dev/disk/by-uuid'): | ||
2628 | 2039 | swaps.append('/dev/' + self._byuuid_to_kname(fs)) | ||
2629 | 2040 | elif fs.startswith('/dev/disk/by-id'): | ||
2630 | 2041 | kname = self._serial_to_kname(os.path.basename(fs)) | ||
2631 | 2042 | swaps.append('/dev/' + kname) | ||
2632 | 2043 | elif fs.startswith('/dev/disk/by-path'): | ||
2633 | 2044 | swaps.append('/dev/' + self._bypath_to_kname(fs)) | ||
2634 | 2045 | else: | ||
2635 | 2046 | swaps.append(fs) | ||
2636 | 2047 | |||
2637 | 2048 | return swaps | ||
2638 | 2049 | |||
2639 | 2050 | # we don't yet have a skip_by_date on specific releases | ||
2640 | 2051 | if is_devel_release(self.target_release): | ||
2641 | 2052 | name = "test_swaps_used" | ||
2642 | 2053 | bug = "1894910" | ||
2643 | 2054 | fixby = "2020-10-15" | ||
2644 | 2055 | removeby = "2020-11-01" | ||
2645 | 2056 | raise SkipTest( | ||
2646 | 2057 | "skip_by_date({name}) LP: #{bug} " | ||
2647 | 2058 | "fixby={fixby} removeby={removeby}: ".format( | ||
2648 | 2059 | name=name, bug=bug, fixby=fixby, removeby=removeby)) | ||
2649 | 1979 | 2060 | ||
2660 | 1980 | swaps_found = [] | 2061 | expected_swaps = find_fstab_swaps() |
2661 | 1981 | for line in self.load_collect_file("proc-swaps").splitlines(): | 2062 | proc_swaps = self.load_collect_file("proc-swaps") |
2662 | 1982 | fname, ttype, size, used, priority = line.split() | 2063 | for swap in expected_swaps: |
2663 | 1983 | if ttype == "partition": | 2064 | self.assertIn(swap, proc_swaps) |
2654 | 1984 | swaps_found.append( | ||
2655 | 1985 | {"fname": fname, ttype: "ttype", "size": int(size), | ||
2656 | 1986 | "used": int(used), "priority": int(priority)}) | ||
2657 | 1987 | self.assertEqual( | ||
2658 | 1988 | len(swap_mounts), len(swaps_found), | ||
2659 | 1989 | "Number swaps configured != number used") | ||
2664 | 1990 | 2065 | ||
2665 | 1991 | 2066 | ||
2666 | 1992 | class PsuedoVMBaseClass(VMBaseClass): | 2067 | class PsuedoVMBaseClass(VMBaseClass): |
2667 | @@ -2085,6 +2160,9 @@ class PsuedoVMBaseClass(VMBaseClass): | |||
2668 | 2085 | def test_kernel_img_conf(self): | 2160 | def test_kernel_img_conf(self): |
2669 | 2086 | pass | 2161 | pass |
2670 | 2087 | 2162 | ||
2671 | 2163 | def test_swaps_used(self): | ||
2672 | 2164 | pass | ||
2673 | 2165 | |||
2674 | 2088 | def _maybe_raise(self, exc): | 2166 | def _maybe_raise(self, exc): |
2675 | 2089 | if self.allow_test_fails: | 2167 | if self.allow_test_fails: |
2676 | 2090 | raise exc | 2168 | raise exc |
2677 | diff --git a/tests/vmtests/releases.py b/tests/vmtests/releases.py | |||
2678 | index 3dcb415..11abcb8 100644 | |||
2679 | --- a/tests/vmtests/releases.py | |||
2680 | +++ b/tests/vmtests/releases.py | |||
2681 | @@ -185,6 +185,14 @@ class _FocalBase(_UbuntuBase): | |||
2682 | 185 | subarch = "ga-20.04" | 185 | subarch = "ga-20.04" |
2683 | 186 | 186 | ||
2684 | 187 | 187 | ||
2685 | 188 | class _GroovyBase(_UbuntuBase): | ||
2686 | 189 | release = "groovy" | ||
2687 | 190 | target_release = "groovy" | ||
2688 | 191 | mem = "2048" | ||
2689 | 192 | if _UbuntuBase.arch == "arm64": | ||
2690 | 193 | subarch = "ga-20.04" | ||
2691 | 194 | |||
2692 | 195 | |||
2693 | 188 | class _Releases(object): | 196 | class _Releases(object): |
2694 | 189 | trusty = _TrustyBase | 197 | trusty = _TrustyBase |
2695 | 190 | precise = _PreciseBase | 198 | precise = _PreciseBase |
2696 | @@ -203,6 +211,7 @@ class _Releases(object): | |||
2697 | 203 | disco = _DiscoBase | 211 | disco = _DiscoBase |
2698 | 204 | eoan = _EoanBase | 212 | eoan = _EoanBase |
2699 | 205 | focal = _FocalBase | 213 | focal = _FocalBase |
2700 | 214 | groovy = _GroovyBase | ||
2701 | 206 | 215 | ||
2702 | 207 | 216 | ||
2703 | 208 | class _CentosReleases(object): | 217 | class _CentosReleases(object): |
2704 | diff --git a/tests/vmtests/test_apt_config_cmd.py b/tests/vmtests/test_apt_config_cmd.py | |||
2705 | index 4e43882..874efad 100644 | |||
2706 | --- a/tests/vmtests/test_apt_config_cmd.py | |||
2707 | +++ b/tests/vmtests/test_apt_config_cmd.py | |||
2708 | @@ -41,7 +41,7 @@ class TestAptConfigCMD(VMBaseClass): | |||
2709 | 41 | self.check_file_regex("curtin-dev-ubuntu-test-archive-%s.list" % | 41 | self.check_file_regex("curtin-dev-ubuntu-test-archive-%s.list" % |
2710 | 42 | self.release, | 42 | self.release, |
2711 | 43 | (r"http://ppa.launchpad.net/" | 43 | (r"http://ppa.launchpad.net/" |
2713 | 44 | r"curtin-dev/test-archive/ubuntu" | 44 | r"curtin-dev/test-archive/ubuntu(/*)" |
2714 | 45 | r" %s main" % self.release)) | 45 | r" %s main" % self.release)) |
2715 | 46 | 46 | ||
2716 | 47 | def test_cmd_preserve_source(self): | 47 | def test_cmd_preserve_source(self): |
2717 | @@ -68,4 +68,8 @@ class FocalTestAptConfigCMDCMD(relbase.focal, TestAptConfigCMD): | |||
2718 | 68 | __test__ = True | 68 | __test__ = True |
2719 | 69 | 69 | ||
2720 | 70 | 70 | ||
2721 | 71 | class GroovyTestAptConfigCMDCMD(relbase.groovy, TestAptConfigCMD): | ||
2722 | 72 | __test__ = True | ||
2723 | 73 | |||
2724 | 74 | |||
2725 | 71 | # vi: ts=4 expandtab syntax=python | 75 | # vi: ts=4 expandtab syntax=python |
2726 | diff --git a/tests/vmtests/test_basic.py b/tests/vmtests/test_basic.py | |||
2727 | index e50318d..5723bc6 100644 | |||
2728 | --- a/tests/vmtests/test_basic.py | |||
2729 | +++ b/tests/vmtests/test_basic.py | |||
2730 | @@ -143,11 +143,16 @@ class TestBasicAbs(VMBaseClass): | |||
2731 | 143 | def get_fstab_expected(self): | 143 | def get_fstab_expected(self): |
2732 | 144 | rootdev = self._serial_to_kname('disk-a') | 144 | rootdev = self._serial_to_kname('disk-a') |
2733 | 145 | btrfsdev = self._serial_to_kname('disk-c') | 145 | btrfsdev = self._serial_to_kname('disk-c') |
2735 | 146 | return [ | 146 | expected = [ |
2736 | 147 | (self._kname_to_byuuid(rootdev + '1'), '/', 'defaults'), | 147 | (self._kname_to_byuuid(rootdev + '1'), '/', 'defaults'), |
2737 | 148 | (self._kname_to_byuuid(rootdev + '2'), '/home', 'defaults'), | 148 | (self._kname_to_byuuid(rootdev + '2'), '/home', 'defaults'), |
2739 | 149 | (self._kname_to_byuuid(btrfsdev), '/btrfs', 'defaults,noatime') | 149 | (self._kname_to_byuuid(btrfsdev), '/btrfs', 'defaults,noatime'), |
2740 | 150 | (self._kname_to_byuuid(rootdev + '3'), 'none', 'sw'), | ||
2741 | 150 | ] | 151 | ] |
2742 | 152 | if self.target_release in ['focal']: | ||
2743 | 153 | expected.append(('/btrfs/btrfsswap.img', 'none', 'sw')) | ||
2744 | 154 | |||
2745 | 155 | return expected | ||
2746 | 151 | 156 | ||
2747 | 152 | def test_whole_disk_uuid(self): | 157 | def test_whole_disk_uuid(self): |
2748 | 153 | self._test_whole_disk_uuid( | 158 | self._test_whole_disk_uuid( |
2749 | @@ -250,11 +255,11 @@ class BionicTestBasic(relbase.bionic, TestBasicAbs): | |||
2750 | 250 | __test__ = True | 255 | __test__ = True |
2751 | 251 | 256 | ||
2752 | 252 | 257 | ||
2754 | 253 | class EoanTestBasic(relbase.eoan, TestBasicAbs): | 258 | class FocalTestBasic(relbase.focal, TestBasicAbs): |
2755 | 254 | __test__ = True | 259 | __test__ = True |
2756 | 255 | 260 | ||
2757 | 256 | 261 | ||
2759 | 257 | class FocalTestBasic(relbase.focal, TestBasicAbs): | 262 | class GroovyTestBasic(relbase.groovy, TestBasicAbs): |
2760 | 258 | __test__ = True | 263 | __test__ = True |
2761 | 259 | 264 | ||
2762 | 260 | 265 | ||
2763 | @@ -307,14 +312,23 @@ class TestBasicScsiAbs(TestBasicAbs): | |||
2764 | 307 | home_kname = ( | 312 | home_kname = ( |
2765 | 308 | self._serial_to_kname('0x39cc071e72c64cc4-part2')) | 313 | self._serial_to_kname('0x39cc071e72c64cc4-part2')) |
2766 | 309 | btrfs_kname = self._serial_to_kname('0x22dc58dc023c7008') | 314 | btrfs_kname = self._serial_to_kname('0x22dc58dc023c7008') |
2767 | 315 | swap_kname = ( | ||
2768 | 316 | self._serial_to_kname('0x39cc071e72c64cc4-part3')) | ||
2769 | 310 | 317 | ||
2770 | 311 | map_func = self._kname_to_byuuid | 318 | map_func = self._kname_to_byuuid |
2771 | 312 | if self.arch == 's390x': | 319 | if self.arch == 's390x': |
2772 | 313 | map_func = self._kname_to_bypath | 320 | map_func = self._kname_to_bypath |
2773 | 314 | 321 | ||
2777 | 315 | return [(map_func(root_kname), '/', 'defaults'), | 322 | expected = [ |
2778 | 316 | (map_func(home_kname), '/home', 'defaults'), | 323 | (map_func(root_kname), '/', 'defaults'), |
2779 | 317 | (map_func(btrfs_kname), '/btrfs', 'defaults,noatime')] | 324 | (map_func(home_kname), '/home', 'defaults'), |
2780 | 325 | (map_func(btrfs_kname), '/btrfs', 'defaults,noatime'), | ||
2781 | 326 | (map_func(swap_kname), 'none', 'sw')] | ||
2782 | 327 | |||
2783 | 328 | if self.target_release in ['focal']: | ||
2784 | 329 | expected.append(('/btrfs/btrfsswap.img', 'none', 'sw')) | ||
2785 | 330 | |||
2786 | 331 | return expected | ||
2787 | 318 | 332 | ||
2788 | 319 | @skip_if_arch('s390x') | 333 | @skip_if_arch('s390x') |
2789 | 320 | def test_whole_disk_uuid(self): | 334 | def test_whole_disk_uuid(self): |
2790 | @@ -340,7 +354,6 @@ class Centos70BionicTestScsiBasic(centos_relbase.centos70_bionic, | |||
2791 | 340 | __test__ = True | 354 | __test__ = True |
2792 | 341 | 355 | ||
2793 | 342 | 356 | ||
2794 | 343 | @VMBaseClass.skip_by_date("1859858", fixby="2020-03-06", install=False) | ||
2795 | 344 | class Centos70FocalTestScsiBasic(centos_relbase.centos70_focal, | 357 | class Centos70FocalTestScsiBasic(centos_relbase.centos70_focal, |
2796 | 345 | TestBasicScsiAbs, CentosTestBasicAbs): | 358 | TestBasicScsiAbs, CentosTestBasicAbs): |
2797 | 346 | __test__ = True | 359 | __test__ = True |
2798 | @@ -362,11 +375,11 @@ class BionicTestScsiBasic(relbase.bionic, TestBasicScsiAbs): | |||
2799 | 362 | __test__ = True | 375 | __test__ = True |
2800 | 363 | 376 | ||
2801 | 364 | 377 | ||
2803 | 365 | class EoanTestScsiBasic(relbase.eoan, TestBasicScsiAbs): | 378 | class FocalTestScsiBasic(relbase.focal, TestBasicScsiAbs): |
2804 | 366 | __test__ = True | 379 | __test__ = True |
2805 | 367 | 380 | ||
2806 | 368 | 381 | ||
2808 | 369 | class FocalTestScsiBasic(relbase.focal, TestBasicScsiAbs): | 382 | class GroovyTestScsiBasic(relbase.groovy, TestBasicScsiAbs): |
2809 | 370 | __test__ = True | 383 | __test__ = True |
2810 | 371 | 384 | ||
2811 | 372 | 385 | ||
2812 | diff --git a/tests/vmtests/test_basic_dasd.py b/tests/vmtests/test_basic_dasd.py | |||
2813 | index 391bafc..d61e1b9 100644 | |||
2814 | --- a/tests/vmtests/test_basic_dasd.py | |||
2815 | +++ b/tests/vmtests/test_basic_dasd.py | |||
2816 | @@ -52,11 +52,11 @@ class BionicTestBasicDasd(relbase.bionic, TestBasicDasd): | |||
2817 | 52 | __test__ = True | 52 | __test__ = True |
2818 | 53 | 53 | ||
2819 | 54 | 54 | ||
2821 | 55 | class EoanTestBasicDasd(relbase.eoan, TestBasicDasd): | 55 | class FocalTestBasicDasd(relbase.focal, TestBasicDasd): |
2822 | 56 | __test__ = True | 56 | __test__ = True |
2823 | 57 | 57 | ||
2824 | 58 | 58 | ||
2826 | 59 | class FocalTestBasicDasd(relbase.focal, TestBasicDasd): | 59 | class GroovyTestBasicDasd(relbase.groovy, TestBasicDasd): |
2827 | 60 | __test__ = True | 60 | __test__ = True |
2828 | 61 | 61 | ||
2829 | 62 | 62 | ||
2830 | diff --git a/tests/vmtests/test_bcache_basic.py b/tests/vmtests/test_bcache_basic.py | |||
2831 | index 54bac81..053225f 100644 | |||
2832 | --- a/tests/vmtests/test_bcache_basic.py | |||
2833 | +++ b/tests/vmtests/test_bcache_basic.py | |||
2834 | @@ -64,11 +64,11 @@ class BionicBcacheBasic(relbase.bionic, TestBcacheBasic): | |||
2835 | 64 | __test__ = True | 64 | __test__ = True |
2836 | 65 | 65 | ||
2837 | 66 | 66 | ||
2839 | 67 | class EoanBcacheBasic(relbase.eoan, TestBcacheBasic): | 67 | class FocalBcacheBasic(relbase.focal, TestBcacheBasic): |
2840 | 68 | __test__ = True | 68 | __test__ = True |
2841 | 69 | 69 | ||
2842 | 70 | 70 | ||
2844 | 71 | class FocalBcacheBasic(relbase.focal, TestBcacheBasic): | 71 | class GroovyBcacheBasic(relbase.groovy, TestBcacheBasic): |
2845 | 72 | __test__ = True | 72 | __test__ = True |
2846 | 73 | 73 | ||
2847 | 74 | 74 | ||
2848 | diff --git a/tests/vmtests/test_bcache_bug1718699.py b/tests/vmtests/test_bcache_bug1718699.py | |||
2849 | index 8c29046..ebb99ab 100644 | |||
2850 | --- a/tests/vmtests/test_bcache_bug1718699.py | |||
2851 | +++ b/tests/vmtests/test_bcache_bug1718699.py | |||
2852 | @@ -19,11 +19,11 @@ class BionicTestBcacheBug1718699(relbase.bionic, TestBcacheBug1718699): | |||
2853 | 19 | __test__ = True | 19 | __test__ = True |
2854 | 20 | 20 | ||
2855 | 21 | 21 | ||
2857 | 22 | class EoanTestBcacheBug1718699(relbase.eoan, TestBcacheBug1718699): | 22 | class FocalTestBcacheBug1718699(relbase.focal, TestBcacheBug1718699): |
2858 | 23 | __test__ = True | 23 | __test__ = True |
2859 | 24 | 24 | ||
2860 | 25 | 25 | ||
2862 | 26 | class FocalTestBcacheBug1718699(relbase.focal, TestBcacheBug1718699): | 26 | class GroovyTestBcacheBug1718699(relbase.groovy, TestBcacheBug1718699): |
2863 | 27 | __test__ = True | 27 | __test__ = True |
2864 | 28 | 28 | ||
2865 | 29 | 29 | ||
2866 | diff --git a/tests/vmtests/test_bcache_ceph.py b/tests/vmtests/test_bcache_ceph.py | |||
2867 | index d24994a..bff4dd4 100644 | |||
2868 | --- a/tests/vmtests/test_bcache_ceph.py | |||
2869 | +++ b/tests/vmtests/test_bcache_ceph.py | |||
2870 | @@ -75,11 +75,11 @@ class BionicTestBcacheCeph(relbase.bionic, TestBcacheCeph): | |||
2871 | 75 | __test__ = True | 75 | __test__ = True |
2872 | 76 | 76 | ||
2873 | 77 | 77 | ||
2875 | 78 | class EoanTestBcacheCeph(relbase.eoan, TestBcacheCeph): | 78 | class FocalTestBcacheCeph(relbase.focal, TestBcacheCeph): |
2876 | 79 | __test__ = True | 79 | __test__ = True |
2877 | 80 | 80 | ||
2878 | 81 | 81 | ||
2880 | 82 | class FocalTestBcacheCeph(relbase.focal, TestBcacheCeph): | 82 | class GroovyTestBcacheCeph(relbase.groovy, TestBcacheCeph): |
2881 | 83 | __test__ = True | 83 | __test__ = True |
2882 | 84 | 84 | ||
2883 | 85 | 85 | ||
2884 | @@ -109,4 +109,8 @@ class FocalTestBcacheCephLvm(relbase.focal, TestBcacheCephLvm): | |||
2885 | 109 | __test__ = True | 109 | __test__ = True |
2886 | 110 | 110 | ||
2887 | 111 | 111 | ||
2888 | 112 | class GroovyTestBcacheCephLvm(relbase.groovy, TestBcacheCephLvm): | ||
2889 | 113 | __test__ = True | ||
2890 | 114 | |||
2891 | 115 | |||
2892 | 112 | # vi: ts=4 expandtab syntax=python | 116 | # vi: ts=4 expandtab syntax=python |
2893 | diff --git a/tests/vmtests/test_bcache_partitions.py b/tests/vmtests/test_bcache_partitions.py | |||
2894 | index f41e645..1ffea12 100644 | |||
2895 | --- a/tests/vmtests/test_bcache_partitions.py | |||
2896 | +++ b/tests/vmtests/test_bcache_partitions.py | |||
2897 | @@ -25,11 +25,11 @@ class BionicTestBcachePartitions(relbase.bionic, TestBcachePartitions): | |||
2898 | 25 | __test__ = True | 25 | __test__ = True |
2899 | 26 | 26 | ||
2900 | 27 | 27 | ||
2902 | 28 | class EoanTestBcachePartitions(relbase.eoan, TestBcachePartitions): | 28 | class FocalTestBcachePartitions(relbase.focal, TestBcachePartitions): |
2903 | 29 | __test__ = True | 29 | __test__ = True |
2904 | 30 | 30 | ||
2905 | 31 | 31 | ||
2907 | 32 | class FocalTestBcachePartitions(relbase.focal, TestBcachePartitions): | 32 | class GroovyTestBcachePartitions(relbase.groovy, TestBcachePartitions): |
2908 | 33 | __test__ = True | 33 | __test__ = True |
2909 | 34 | 34 | ||
2910 | 35 | 35 | ||
2911 | diff --git a/tests/vmtests/test_fs_battery.py b/tests/vmtests/test_fs_battery.py | |||
2912 | index bd44905..7177fea 100644 | |||
2913 | --- a/tests/vmtests/test_fs_battery.py | |||
2914 | +++ b/tests/vmtests/test_fs_battery.py | |||
2915 | @@ -239,11 +239,11 @@ class BionicTestFsBattery(relbase.bionic, TestFsBattery): | |||
2916 | 239 | __test__ = True | 239 | __test__ = True |
2917 | 240 | 240 | ||
2918 | 241 | 241 | ||
2920 | 242 | class EoanTestFsBattery(relbase.eoan, TestFsBattery): | 242 | class FocalTestFsBattery(relbase.focal, TestFsBattery): |
2921 | 243 | __test__ = True | 243 | __test__ = True |
2922 | 244 | 244 | ||
2923 | 245 | 245 | ||
2925 | 246 | class FocalTestFsBattery(relbase.focal, TestFsBattery): | 246 | class GroovyTestFsBattery(relbase.groovy, TestFsBattery): |
2926 | 247 | __test__ = True | 247 | __test__ = True |
2927 | 248 | 248 | ||
2928 | 249 | 249 | ||
2929 | diff --git a/tests/vmtests/test_iscsi.py b/tests/vmtests/test_iscsi.py | |||
2930 | index c99264c..f3406cd 100644 | |||
2931 | --- a/tests/vmtests/test_iscsi.py | |||
2932 | +++ b/tests/vmtests/test_iscsi.py | |||
2933 | @@ -72,11 +72,11 @@ class BionicTestIscsiBasic(relbase.bionic, TestBasicIscsiAbs): | |||
2934 | 72 | __test__ = True | 72 | __test__ = True |
2935 | 73 | 73 | ||
2936 | 74 | 74 | ||
2938 | 75 | class EoanTestIscsiBasic(relbase.eoan, TestBasicIscsiAbs): | 75 | class FocalTestIscsiBasic(relbase.focal, TestBasicIscsiAbs): |
2939 | 76 | __test__ = True | 76 | __test__ = True |
2940 | 77 | 77 | ||
2941 | 78 | 78 | ||
2943 | 79 | class FocalTestIscsiBasic(relbase.focal, TestBasicIscsiAbs): | 79 | class GroovyTestIscsiBasic(relbase.groovy, TestBasicIscsiAbs): |
2944 | 80 | __test__ = True | 80 | __test__ = True |
2945 | 81 | 81 | ||
2946 | 82 | 82 | ||
2947 | diff --git a/tests/vmtests/test_journald_reporter.py b/tests/vmtests/test_journald_reporter.py | |||
2948 | index d29b4d4..ff003a5 100644 | |||
2949 | --- a/tests/vmtests/test_journald_reporter.py | |||
2950 | +++ b/tests/vmtests/test_journald_reporter.py | |||
2951 | @@ -32,11 +32,11 @@ class BionicTestJournaldReporter(relbase.bionic, TestJournaldReporter): | |||
2952 | 32 | __test__ = True | 32 | __test__ = True |
2953 | 33 | 33 | ||
2954 | 34 | 34 | ||
2956 | 35 | class EoanTestJournaldReporter(relbase.eoan, TestJournaldReporter): | 35 | class FocalTestJournaldReporter(relbase.focal, TestJournaldReporter): |
2957 | 36 | __test__ = True | 36 | __test__ = True |
2958 | 37 | 37 | ||
2959 | 38 | 38 | ||
2961 | 39 | class FocalTestJournaldReporter(relbase.focal, TestJournaldReporter): | 39 | class GroovyTestJournaldReporter(relbase.groovy, TestJournaldReporter): |
2962 | 40 | __test__ = True | 40 | __test__ = True |
2963 | 41 | 41 | ||
2964 | 42 | 42 | ||
2965 | diff --git a/tests/vmtests/test_lvm.py b/tests/vmtests/test_lvm.py | |||
2966 | index a79a705..eb65c32 100644 | |||
2967 | --- a/tests/vmtests/test_lvm.py | |||
2968 | +++ b/tests/vmtests/test_lvm.py | |||
2969 | @@ -77,11 +77,11 @@ class BionicTestLvm(relbase.bionic, TestLvmAbs): | |||
2970 | 77 | __test__ = True | 77 | __test__ = True |
2971 | 78 | 78 | ||
2972 | 79 | 79 | ||
2974 | 80 | class EoanTestLvm(relbase.eoan, TestLvmAbs): | 80 | class FocalTestLvm(relbase.focal, TestLvmAbs): |
2975 | 81 | __test__ = True | 81 | __test__ = True |
2976 | 82 | 82 | ||
2977 | 83 | 83 | ||
2979 | 84 | class FocalTestLvm(relbase.focal, TestLvmAbs): | 84 | class GroovyTestLvm(relbase.groovy, TestLvmAbs): |
2980 | 85 | __test__ = True | 85 | __test__ = True |
2981 | 86 | 86 | ||
2982 | 87 | 87 | ||
2983 | diff --git a/tests/vmtests/test_lvm_iscsi.py b/tests/vmtests/test_lvm_iscsi.py | |||
2984 | index 077b31a..e0b9606 100644 | |||
2985 | --- a/tests/vmtests/test_lvm_iscsi.py | |||
2986 | +++ b/tests/vmtests/test_lvm_iscsi.py | |||
2987 | @@ -95,11 +95,11 @@ class BionicTestIscsiLvm(relbase.bionic, TestLvmIscsiAbs): | |||
2988 | 95 | __test__ = True | 95 | __test__ = True |
2989 | 96 | 96 | ||
2990 | 97 | 97 | ||
2992 | 98 | class EoanTestIscsiLvm(relbase.eoan, TestLvmIscsiAbs): | 98 | class FocalTestIscsiLvm(relbase.focal, TestLvmIscsiAbs): |
2993 | 99 | __test__ = True | 99 | __test__ = True |
2994 | 100 | 100 | ||
2995 | 101 | 101 | ||
2997 | 102 | class FocalTestIscsiLvm(relbase.focal, TestLvmIscsiAbs): | 102 | class GroovyTestIscsiLvm(relbase.groovy, TestLvmIscsiAbs): |
2998 | 103 | __test__ = True | 103 | __test__ = True |
2999 | 104 | 104 | ||
3000 | 105 | 105 | ||
3001 | diff --git a/tests/vmtests/test_lvm_raid.py b/tests/vmtests/test_lvm_raid.py | |||
3002 | index 8d42a1a..5fe7993 100644 | |||
3003 | --- a/tests/vmtests/test_lvm_raid.py | |||
3004 | +++ b/tests/vmtests/test_lvm_raid.py | |||
3005 | @@ -47,17 +47,17 @@ class TestLvmOverRaidAbs(TestMdadmAbs, TestLvmAbs): | |||
3006 | 47 | return self._test_pvs(dname_to_vg) | 47 | return self._test_pvs(dname_to_vg) |
3007 | 48 | 48 | ||
3008 | 49 | 49 | ||
3010 | 50 | class FocalTestLvmOverRaid(relbase.focal, TestLvmOverRaidAbs): | 50 | class XenialGATestLvmOverRaid(relbase.xenial_ga, TestLvmOverRaidAbs): |
3011 | 51 | __test__ = True | 51 | __test__ = True |
3012 | 52 | 52 | ||
3013 | 53 | 53 | ||
3015 | 54 | class EoanTestLvmOverRaid(relbase.eoan, TestLvmOverRaidAbs): | 54 | class BionicTestLvmOverRaid(relbase.bionic, TestLvmOverRaidAbs): |
3016 | 55 | __test__ = True | 55 | __test__ = True |
3017 | 56 | 56 | ||
3018 | 57 | 57 | ||
3020 | 58 | class BionicTestLvmOverRaid(relbase.bionic, TestLvmOverRaidAbs): | 58 | class FocalTestLvmOverRaid(relbase.focal, TestLvmOverRaidAbs): |
3021 | 59 | __test__ = True | 59 | __test__ = True |
3022 | 60 | 60 | ||
3023 | 61 | 61 | ||
3025 | 62 | class XenialGATestLvmOverRaid(relbase.xenial_ga, TestLvmOverRaidAbs): | 62 | class GroovyTestLvmOverRaid(relbase.groovy, TestLvmOverRaidAbs): |
3026 | 63 | __test__ = True | 63 | __test__ = True |
3027 | diff --git a/tests/vmtests/test_lvm_root.py b/tests/vmtests/test_lvm_root.py | |||
3028 | index 117406e..12b8ea8 100644 | |||
3029 | --- a/tests/vmtests/test_lvm_root.py | |||
3030 | +++ b/tests/vmtests/test_lvm_root.py | |||
3031 | @@ -94,6 +94,13 @@ class FocalTestLvmRootExt4(relbase.focal, TestLvmRootAbs): | |||
3032 | 94 | } | 94 | } |
3033 | 95 | 95 | ||
3034 | 96 | 96 | ||
3035 | 97 | class GroovyTestLvmRootExt4(relbase.groovy, TestLvmRootAbs): | ||
3036 | 98 | __test__ = True | ||
3037 | 99 | conf_replace = { | ||
3038 | 100 | '__ROOTFS_FORMAT__': 'ext4', | ||
3039 | 101 | } | ||
3040 | 102 | |||
3041 | 103 | |||
3042 | 97 | class XenialTestLvmRootXfs(relbase.xenial, TestLvmRootAbs): | 104 | class XenialTestLvmRootXfs(relbase.xenial, TestLvmRootAbs): |
3043 | 98 | __test__ = True | 105 | __test__ = True |
3044 | 99 | conf_replace = { | 106 | conf_replace = { |
3045 | @@ -140,6 +147,14 @@ class FocalTestUefiLvmRootExt4(relbase.focal, TestUefiLvmRootAbs): | |||
3046 | 140 | } | 147 | } |
3047 | 141 | 148 | ||
3048 | 142 | 149 | ||
3049 | 150 | class GroovyTestUefiLvmRootExt4(relbase.groovy, TestUefiLvmRootAbs): | ||
3050 | 151 | __test__ = True | ||
3051 | 152 | conf_replace = { | ||
3052 | 153 | '__BOOTFS_FORMAT__': 'ext4', | ||
3053 | 154 | '__ROOTFS_FORMAT__': 'ext4', | ||
3054 | 155 | } | ||
3055 | 156 | |||
3056 | 157 | |||
3057 | 143 | class XenialTestUefiLvmRootXfs(relbase.xenial, TestUefiLvmRootAbs): | 158 | class XenialTestUefiLvmRootXfs(relbase.xenial, TestUefiLvmRootAbs): |
3058 | 144 | __test__ = True | 159 | __test__ = True |
3059 | 145 | conf_replace = { | 160 | conf_replace = { |
3060 | @@ -148,13 +163,11 @@ class XenialTestUefiLvmRootXfs(relbase.xenial, TestUefiLvmRootAbs): | |||
3061 | 148 | } | 163 | } |
3062 | 149 | 164 | ||
3063 | 150 | 165 | ||
3064 | 151 | @VMBaseClass.skip_by_date("1652822", fixby="2020-06-01", install=False) | ||
3065 | 152 | class XenialTestUefiLvmRootXfsBootXfs(relbase.xenial, TestUefiLvmRootAbs): | 166 | class XenialTestUefiLvmRootXfsBootXfs(relbase.xenial, TestUefiLvmRootAbs): |
3066 | 153 | """This tests xfs root and xfs boot with uefi. | 167 | """This tests xfs root and xfs boot with uefi. |
3067 | 154 | 168 | ||
3071 | 155 | It is known broken (LP: #1652822) and unlikely to be fixed without pushing, | 169 | It is known broken (LP: #1652822) and unlikely to be fixed.""" |
3072 | 156 | so we skip-by for a long time.""" | 170 | __test__ = False |
3070 | 157 | __test__ = True | ||
3073 | 158 | conf_replace = { | 171 | conf_replace = { |
3074 | 159 | '__BOOTFS_FORMAT__': 'xfs', | 172 | '__BOOTFS_FORMAT__': 'xfs', |
3075 | 160 | '__ROOTFS_FORMAT__': 'xfs', | 173 | '__ROOTFS_FORMAT__': 'xfs', |
3076 | diff --git a/tests/vmtests/test_mdadm_bcache.py b/tests/vmtests/test_mdadm_bcache.py | |||
3077 | index 53637ae..5425221 100644 | |||
3078 | --- a/tests/vmtests/test_mdadm_bcache.py | |||
3079 | +++ b/tests/vmtests/test_mdadm_bcache.py | |||
3080 | @@ -26,6 +26,7 @@ class TestMdadmAbs(VMBaseClass): | |||
3081 | 26 | ls -al /dev/bcache* > lsal_dev_bcache_star | 26 | ls -al /dev/bcache* > lsal_dev_bcache_star |
3082 | 27 | ls -al /dev/bcache/by-uuid/ | cat >ls_al_bcache_byuuid | 27 | ls -al /dev/bcache/by-uuid/ | cat >ls_al_bcache_byuuid |
3083 | 28 | ls -al /dev/bcache/by-label/ | cat >ls_al_bcache_bylabel | 28 | ls -al /dev/bcache/by-label/ | cat >ls_al_bcache_bylabel |
3084 | 29 | ls -al /dev/md/* | cat >ls_al_dev_md | ||
3085 | 29 | 30 | ||
3086 | 30 | exit 0 | 31 | exit 0 |
3087 | 31 | """)] | 32 | """)] |
3088 | @@ -153,18 +154,18 @@ class BionicTestMdadmBcache(relbase.bionic, TestMdadmBcacheAbs): | |||
3089 | 153 | __test__ = True | 154 | __test__ = True |
3090 | 154 | 155 | ||
3091 | 155 | 156 | ||
3092 | 156 | class EoanTestMdadmBcache(relbase.eoan, TestMdadmBcacheAbs): | ||
3093 | 157 | __test__ = True | ||
3094 | 158 | |||
3095 | 159 | |||
3096 | 160 | class FocalTestMdadmBcache(relbase.focal, TestMdadmBcacheAbs): | 157 | class FocalTestMdadmBcache(relbase.focal, TestMdadmBcacheAbs): |
3097 | 161 | __test__ = True | 158 | __test__ = True |
3098 | 162 | 159 | ||
3100 | 163 | @TestMdadmBcacheAbs.skip_by_date("1861941", fixby="2020-04-15") | 160 | @TestMdadmBcacheAbs.skip_by_date("1861941", fixby="2020-09-15") |
3101 | 164 | def test_fstab(self): | 161 | def test_fstab(self): |
3102 | 165 | return super().test_fstab() | 162 | return super().test_fstab() |
3103 | 166 | 163 | ||
3104 | 167 | 164 | ||
3105 | 165 | class GroovyTestMdadmBcache(relbase.groovy, TestMdadmBcacheAbs): | ||
3106 | 166 | __test__ = True | ||
3107 | 167 | |||
3108 | 168 | |||
3109 | 168 | class TestMirrorbootAbs(TestMdadmAbs): | 169 | class TestMirrorbootAbs(TestMdadmAbs): |
3110 | 169 | # alternative config for more complex setup | 170 | # alternative config for more complex setup |
3111 | 170 | conf_file = "examples/tests/mirrorboot.yaml" | 171 | conf_file = "examples/tests/mirrorboot.yaml" |
3112 | @@ -202,11 +203,11 @@ class BionicTestMirrorboot(relbase.bionic, TestMirrorbootAbs): | |||
3113 | 202 | __test__ = True | 203 | __test__ = True |
3114 | 203 | 204 | ||
3115 | 204 | 205 | ||
3117 | 205 | class EoanTestMirrorboot(relbase.eoan, TestMirrorbootAbs): | 206 | class FocalTestMirrorboot(relbase.focal, TestMirrorbootAbs): |
3118 | 206 | __test__ = True | 207 | __test__ = True |
3119 | 207 | 208 | ||
3120 | 208 | 209 | ||
3122 | 209 | class FocalTestMirrorboot(relbase.focal, TestMirrorbootAbs): | 210 | class GroovyTestMirrorboot(relbase.groovy, TestMirrorbootAbs): |
3123 | 210 | __test__ = True | 211 | __test__ = True |
3124 | 211 | 212 | ||
3125 | 212 | 213 | ||
3126 | @@ -250,13 +251,13 @@ class BionicTestMirrorbootPartitions(relbase.bionic, | |||
3127 | 250 | __test__ = True | 251 | __test__ = True |
3128 | 251 | 252 | ||
3129 | 252 | 253 | ||
3132 | 253 | class EoanTestMirrorbootPartitions(relbase.eoan, | 254 | class FocalTestMirrorbootPartitions(relbase.focal, |
3133 | 254 | TestMirrorbootPartitionsAbs): | 255 | TestMirrorbootPartitionsAbs): |
3134 | 255 | __test__ = True | 256 | __test__ = True |
3135 | 256 | 257 | ||
3136 | 257 | 258 | ||
3139 | 258 | class FocalTestMirrorbootPartitions(relbase.focal, | 259 | class GroovyTestMirrorbootPartitions(relbase.groovy, |
3140 | 259 | TestMirrorbootPartitionsAbs): | 260 | TestMirrorbootPartitionsAbs): |
3141 | 260 | __test__ = True | 261 | __test__ = True |
3142 | 261 | 262 | ||
3143 | 262 | 263 | ||
3144 | @@ -309,6 +310,16 @@ class TestMirrorbootPartitionsUEFIAbs(TestMdadmAbs): | |||
3145 | 309 | self.assertIn( | 310 | self.assertIn( |
3146 | 310 | ('grub-pc', 'grub-efi/install_devices', choice), found_selections) | 311 | ('grub-pc', 'grub-efi/install_devices', choice), found_selections) |
3147 | 311 | 312 | ||
3148 | 313 | def test_backup_esp_matches_primary(self): | ||
3149 | 314 | if self.target_distro != "ubuntu": | ||
3150 | 315 | raise SkipTest("backup ESP supported only on Ubuntu") | ||
3151 | 316 | if self.target_release in [ | ||
3152 | 317 | "trusty", "xenial", "bionic", "cosmic", "disco", "eoan"]: | ||
3153 | 318 | raise SkipTest("backup ESP supported only on >= Focal") | ||
3154 | 319 | primary_esp = self.load_collect_file("diska-part1-efi.out") | ||
3155 | 320 | backup_esp = self.load_collect_file("diskb-part1-efi.out") | ||
3156 | 321 | self.assertEqual(primary_esp, backup_esp) | ||
3157 | 322 | |||
3158 | 312 | 323 | ||
3159 | 313 | class Centos70TestMirrorbootPartitionsUEFI(centos_relbase.centos70_xenial, | 324 | class Centos70TestMirrorbootPartitionsUEFI(centos_relbase.centos70_xenial, |
3160 | 314 | TestMirrorbootPartitionsUEFIAbs): | 325 | TestMirrorbootPartitionsUEFIAbs): |
3161 | @@ -335,19 +346,14 @@ class BionicTestMirrorbootPartitionsUEFI(relbase.bionic, | |||
3162 | 335 | __test__ = True | 346 | __test__ = True |
3163 | 336 | 347 | ||
3164 | 337 | 348 | ||
3165 | 338 | class EoanTestMirrorbootPartitionsUEFI(relbase.eoan, | ||
3166 | 339 | TestMirrorbootPartitionsUEFIAbs): | ||
3167 | 340 | __test__ = True | ||
3168 | 341 | |||
3169 | 342 | |||
3170 | 343 | class FocalTestMirrorbootPartitionsUEFI(relbase.focal, | 349 | class FocalTestMirrorbootPartitionsUEFI(relbase.focal, |
3171 | 344 | TestMirrorbootPartitionsUEFIAbs): | 350 | TestMirrorbootPartitionsUEFIAbs): |
3172 | 345 | __test__ = True | 351 | __test__ = True |
3173 | 346 | 352 | ||
3178 | 347 | def test_backup_esp_matches_primary(self): | 353 | |
3179 | 348 | primary_esp = self.load_collect_file("diska-part1-efi.out") | 354 | class GroovyTestMirrorbootPartitionsUEFI(relbase.groovy, |
3180 | 349 | backup_esp = self.load_collect_file("diskb-part1-efi.out") | 355 | TestMirrorbootPartitionsUEFIAbs): |
3181 | 350 | self.assertEqual(primary_esp, backup_esp) | 356 | __test__ = True |
3182 | 351 | 357 | ||
3183 | 352 | 358 | ||
3184 | 353 | class TestRaid5bootAbs(TestMdadmAbs): | 359 | class TestRaid5bootAbs(TestMdadmAbs): |
3185 | @@ -359,11 +365,14 @@ class TestRaid5bootAbs(TestMdadmAbs): | |||
3186 | 359 | ('main_disk', 2), | 365 | ('main_disk', 2), |
3187 | 360 | ('second_disk', 1), | 366 | ('second_disk', 1), |
3188 | 361 | ('third_disk', 1), | 367 | ('third_disk', 1), |
3190 | 362 | ('md0', 0)] | 368 | ('os-raid1', 0)] |
3191 | 363 | 369 | ||
3192 | 364 | def get_fstab_expected(self): | 370 | def get_fstab_expected(self): |
3193 | 371 | kname = self._mdname_to_kname('os-raid1') | ||
3194 | 365 | return [ | 372 | return [ |
3196 | 366 | (self._kname_to_uuid_devpath('md-uuid', 'md0'), '/', 'defaults'), | 373 | (self._kname_to_uuid_devpath('md-uuid', kname), |
3197 | 374 | '/', | ||
3198 | 375 | 'defaults'), | ||
3199 | 367 | ] | 376 | ] |
3200 | 368 | 377 | ||
3201 | 369 | 378 | ||
3202 | @@ -387,11 +396,11 @@ class BionicTestRaid5boot(relbase.bionic, TestRaid5bootAbs): | |||
3203 | 387 | __test__ = True | 396 | __test__ = True |
3204 | 388 | 397 | ||
3205 | 389 | 398 | ||
3207 | 390 | class EoanTestRaid5boot(relbase.eoan, TestRaid5bootAbs): | 399 | class FocalTestRaid5boot(relbase.focal, TestRaid5bootAbs): |
3208 | 391 | __test__ = True | 400 | __test__ = True |
3209 | 392 | 401 | ||
3210 | 393 | 402 | ||
3212 | 394 | class FocalTestRaid5boot(relbase.focal, TestRaid5bootAbs): | 403 | class GroovyTestRaid5boot(relbase.groovy, TestRaid5bootAbs): |
3213 | 395 | __test__ = True | 404 | __test__ = True |
3214 | 396 | 405 | ||
3215 | 397 | 406 | ||
3216 | @@ -448,11 +457,11 @@ class BionicTestRaid6boot(relbase.bionic, TestRaid6bootAbs): | |||
3217 | 448 | __test__ = True | 457 | __test__ = True |
3218 | 449 | 458 | ||
3219 | 450 | 459 | ||
3221 | 451 | class EoanTestRaid6boot(relbase.eoan, TestRaid6bootAbs): | 460 | class FocalTestRaid6boot(relbase.focal, TestRaid6bootAbs): |
3222 | 452 | __test__ = True | 461 | __test__ = True |
3223 | 453 | 462 | ||
3224 | 454 | 463 | ||
3226 | 455 | class FocalTestRaid6boot(relbase.focal, TestRaid6bootAbs): | 464 | class GroovyTestRaid6boot(relbase.groovy, TestRaid6bootAbs): |
3227 | 456 | __test__ = True | 465 | __test__ = True |
3228 | 457 | 466 | ||
3229 | 458 | 467 | ||
3230 | @@ -495,11 +504,11 @@ class BionicTestRaid10boot(relbase.bionic, TestRaid10bootAbs): | |||
3231 | 495 | __test__ = True | 504 | __test__ = True |
3232 | 496 | 505 | ||
3233 | 497 | 506 | ||
3235 | 498 | class EoanTestRaid10boot(relbase.eoan, TestRaid10bootAbs): | 507 | class FocalTestRaid10boot(relbase.focal, TestRaid10bootAbs): |
3236 | 499 | __test__ = True | 508 | __test__ = True |
3237 | 500 | 509 | ||
3238 | 501 | 510 | ||
3240 | 502 | class FocalTestRaid10boot(relbase.focal, TestRaid10bootAbs): | 511 | class GroovyTestRaid10boot(relbase.groovy, TestRaid10bootAbs): |
3241 | 503 | __test__ = True | 512 | __test__ = True |
3242 | 504 | 513 | ||
3243 | 505 | 514 | ||
3244 | @@ -599,11 +608,11 @@ class BionicTestAllindata(relbase.bionic, TestAllindataAbs): | |||
3245 | 599 | __test__ = True | 608 | __test__ = True |
3246 | 600 | 609 | ||
3247 | 601 | 610 | ||
3249 | 602 | class EoanTestAllindata(relbase.eoan, TestAllindataAbs): | 611 | class FocalTestAllindata(relbase.focal, TestAllindataAbs): |
3250 | 603 | __test__ = True | 612 | __test__ = True |
3251 | 604 | 613 | ||
3252 | 605 | 614 | ||
3254 | 606 | class FocalTestAllindata(relbase.focal, TestAllindataAbs): | 615 | class GroovyTestAllindata(relbase.groovy, TestAllindataAbs): |
3255 | 607 | __test__ = True | 616 | __test__ = True |
3256 | 608 | 617 | ||
3257 | 609 | 618 | ||
3258 | diff --git a/tests/vmtests/test_mdadm_iscsi.py b/tests/vmtests/test_mdadm_iscsi.py | |||
3259 | index 26b1f71..7e6fbf6 100644 | |||
3260 | --- a/tests/vmtests/test_mdadm_iscsi.py | |||
3261 | +++ b/tests/vmtests/test_mdadm_iscsi.py | |||
3262 | @@ -50,11 +50,11 @@ class BionicTestIscsiMdadm(relbase.bionic, TestMdadmIscsiAbs): | |||
3263 | 50 | __test__ = True | 50 | __test__ = True |
3264 | 51 | 51 | ||
3265 | 52 | 52 | ||
3267 | 53 | class EoanTestIscsiMdadm(relbase.eoan, TestMdadmIscsiAbs): | 53 | class FocalTestIscsiMdadm(relbase.focal, TestMdadmIscsiAbs): |
3268 | 54 | __test__ = True | 54 | __test__ = True |
3269 | 55 | 55 | ||
3270 | 56 | 56 | ||
3272 | 57 | class FocalTestIscsiMdadm(relbase.focal, TestMdadmIscsiAbs): | 57 | class GroovyTestIscsiMdadm(relbase.groovy, TestMdadmIscsiAbs): |
3273 | 58 | __test__ = True | 58 | __test__ = True |
3274 | 59 | 59 | ||
3275 | 60 | 60 | ||
3276 | diff --git a/tests/vmtests/test_multipath.py b/tests/vmtests/test_multipath.py | |||
3277 | index 7c7e621..6d9c5df 100644 | |||
3278 | --- a/tests/vmtests/test_multipath.py | |||
3279 | +++ b/tests/vmtests/test_multipath.py | |||
3280 | @@ -158,11 +158,11 @@ class BionicTestMultipathBasic(relbase.bionic, TestMultipathBasicAbs): | |||
3281 | 158 | __test__ = True | 158 | __test__ = True |
3282 | 159 | 159 | ||
3283 | 160 | 160 | ||
3285 | 161 | class EoanTestMultipathBasic(relbase.eoan, TestMultipathBasicAbs): | 161 | class FocalTestMultipathBasic(relbase.focal, TestMultipathBasicAbs): |
3286 | 162 | __test__ = True | 162 | __test__ = True |
3287 | 163 | 163 | ||
3288 | 164 | 164 | ||
3290 | 165 | class FocalTestMultipathBasic(relbase.focal, TestMultipathBasicAbs): | 165 | class GroovyTestMultipathBasic(relbase.groovy, TestMultipathBasicAbs): |
3291 | 166 | __test__ = True | 166 | __test__ = True |
3292 | 167 | 167 | ||
3293 | 168 | 168 | ||
3294 | diff --git a/tests/vmtests/test_multipath_lvm.py b/tests/vmtests/test_multipath_lvm.py | |||
3295 | index 39b8587..c5a1e42 100644 | |||
3296 | --- a/tests/vmtests/test_multipath_lvm.py | |||
3297 | +++ b/tests/vmtests/test_multipath_lvm.py | |||
3298 | @@ -56,11 +56,11 @@ class BionicTestMultipathLvm(relbase.bionic, TestMultipathLvmAbs): | |||
3299 | 56 | __test__ = True | 56 | __test__ = True |
3300 | 57 | 57 | ||
3301 | 58 | 58 | ||
3303 | 59 | class EoanTestMultipathLvm(relbase.eoan, TestMultipathLvmAbs): | 59 | class FocalTestMultipathLvm(relbase.focal, TestMultipathLvmAbs): |
3304 | 60 | __test__ = True | 60 | __test__ = True |
3305 | 61 | 61 | ||
3306 | 62 | 62 | ||
3308 | 63 | class FocalTestMultipathLvm(relbase.focal, TestMultipathLvmAbs): | 63 | class GroovyTestMultipathLvm(relbase.groovy, TestMultipathLvmAbs): |
3309 | 64 | __test__ = True | 64 | __test__ = True |
3310 | 65 | 65 | ||
3311 | 66 | 66 | ||
3312 | @@ -73,4 +73,9 @@ class FocalTestMultipathLvmPartWipe(relbase.focal, | |||
3313 | 73 | __test__ = True | 73 | __test__ = True |
3314 | 74 | 74 | ||
3315 | 75 | 75 | ||
3316 | 76 | class GroovyTestMultipathLvmPartWipe(relbase.groovy, | ||
3317 | 77 | TestMultipathLvmPartWipeAbs): | ||
3318 | 78 | __test__ = True | ||
3319 | 79 | |||
3320 | 80 | |||
3321 | 76 | # vi: ts=4 expandtab syntax=python | 81 | # vi: ts=4 expandtab syntax=python |
3322 | diff --git a/tests/vmtests/test_network.py b/tests/vmtests/test_network.py | |||
3323 | index e6ea6e2..43a7c6b 100644 | |||
3324 | --- a/tests/vmtests/test_network.py | |||
3325 | +++ b/tests/vmtests/test_network.py | |||
3326 | @@ -474,11 +474,11 @@ class BionicTestNetworkBasic(relbase.bionic, TestNetworkBasicAbs): | |||
3327 | 474 | __test__ = True | 474 | __test__ = True |
3328 | 475 | 475 | ||
3329 | 476 | 476 | ||
3331 | 477 | class EoanTestNetworkBasic(relbase.eoan, TestNetworkBasicAbs): | 477 | class FocalTestNetworkBasic(relbase.focal, TestNetworkBasicAbs): |
3332 | 478 | __test__ = True | 478 | __test__ = True |
3333 | 479 | 479 | ||
3334 | 480 | 480 | ||
3336 | 481 | class FocalTestNetworkBasic(relbase.focal, TestNetworkBasicAbs): | 481 | class GroovyTestNetworkBasic(relbase.groovy, TestNetworkBasicAbs): |
3337 | 482 | __test__ = True | 482 | __test__ = True |
3338 | 483 | 483 | ||
3339 | 484 | 484 | ||
3340 | diff --git a/tests/vmtests/test_network_alias.py b/tests/vmtests/test_network_alias.py | |||
3341 | index 68e7de4..bc1fb22 100644 | |||
3342 | --- a/tests/vmtests/test_network_alias.py | |||
3343 | +++ b/tests/vmtests/test_network_alias.py | |||
3344 | @@ -52,11 +52,11 @@ class BionicTestNetworkAlias(relbase.bionic, TestNetworkAliasAbs): | |||
3345 | 52 | __test__ = True | 52 | __test__ = True |
3346 | 53 | 53 | ||
3347 | 54 | 54 | ||
3349 | 55 | class EoanTestNetworkAlias(relbase.eoan, TestNetworkAliasAbs): | 55 | class FocalTestNetworkAlias(relbase.focal, TestNetworkAliasAbs): |
3350 | 56 | __test__ = True | 56 | __test__ = True |
3351 | 57 | 57 | ||
3352 | 58 | 58 | ||
3354 | 59 | class FocalTestNetworkAlias(relbase.focal, TestNetworkAliasAbs): | 59 | class GroovyTestNetworkAlias(relbase.groovy, TestNetworkAliasAbs): |
3355 | 60 | __test__ = True | 60 | __test__ = True |
3356 | 61 | 61 | ||
3357 | 62 | 62 | ||
3358 | diff --git a/tests/vmtests/test_network_bonding.py b/tests/vmtests/test_network_bonding.py | |||
3359 | index 913c7ff..6c6dd6d 100644 | |||
3360 | --- a/tests/vmtests/test_network_bonding.py | |||
3361 | +++ b/tests/vmtests/test_network_bonding.py | |||
3362 | @@ -57,11 +57,11 @@ class BionicTestBonding(relbase.bionic, TestNetworkBondingAbs): | |||
3363 | 57 | __test__ = True | 57 | __test__ = True |
3364 | 58 | 58 | ||
3365 | 59 | 59 | ||
3367 | 60 | class EoanTestBonding(relbase.eoan, TestNetworkBondingAbs): | 60 | class FocalTestBonding(relbase.focal, TestNetworkBondingAbs): |
3368 | 61 | __test__ = True | 61 | __test__ = True |
3369 | 62 | 62 | ||
3370 | 63 | 63 | ||
3372 | 64 | class FocalTestBonding(relbase.focal, TestNetworkBondingAbs): | 64 | class GroovyTestBonding(relbase.groovy, TestNetworkBondingAbs): |
3373 | 65 | __test__ = True | 65 | __test__ = True |
3374 | 66 | 66 | ||
3375 | 67 | 67 | ||
3376 | diff --git a/tests/vmtests/test_network_bridging.py b/tests/vmtests/test_network_bridging.py | |||
3377 | index daaade5..9ecd2f6 100644 | |||
3378 | --- a/tests/vmtests/test_network_bridging.py | |||
3379 | +++ b/tests/vmtests/test_network_bridging.py | |||
3380 | @@ -236,11 +236,11 @@ class BionicTestBridging(relbase.bionic, TestBridgeNetworkAbs): | |||
3381 | 236 | __test__ = True | 236 | __test__ = True |
3382 | 237 | 237 | ||
3383 | 238 | 238 | ||
3385 | 239 | class EoanTestBridging(relbase.eoan, TestBridgeNetworkAbs): | 239 | class FocalTestBridging(relbase.focal, TestBridgeNetworkAbs): |
3386 | 240 | __test__ = True | 240 | __test__ = True |
3387 | 241 | 241 | ||
3388 | 242 | 242 | ||
3390 | 243 | class FocalTestBridging(relbase.focal, TestBridgeNetworkAbs): | 243 | class GroovyTestBridging(relbase.groovy, TestBridgeNetworkAbs): |
3391 | 244 | __test__ = True | 244 | __test__ = True |
3392 | 245 | 245 | ||
3393 | 246 | 246 | ||
3394 | diff --git a/tests/vmtests/test_network_disabled.py b/tests/vmtests/test_network_disabled.py | |||
3395 | index b19ca64..ea8dae2 100644 | |||
3396 | --- a/tests/vmtests/test_network_disabled.py | |||
3397 | +++ b/tests/vmtests/test_network_disabled.py | |||
3398 | @@ -57,6 +57,11 @@ class FocalCurtinDisableNetworkRendering(relbase.focal, | |||
3399 | 57 | __test__ = True | 57 | __test__ = True |
3400 | 58 | 58 | ||
3401 | 59 | 59 | ||
3402 | 60 | class GroovyCurtinDisableNetworkRendering(relbase.groovy, | ||
3403 | 61 | CurtinDisableNetworkRendering): | ||
3404 | 62 | __test__ = True | ||
3405 | 63 | |||
3406 | 64 | |||
3407 | 60 | class FocalCurtinDisableCloudInitNetworkingVersion1( | 65 | class FocalCurtinDisableCloudInitNetworkingVersion1( |
3408 | 61 | relbase.focal, | 66 | relbase.focal, |
3409 | 62 | CurtinDisableCloudInitNetworkingVersion1 | 67 | CurtinDisableCloudInitNetworkingVersion1 |
3410 | @@ -64,9 +69,21 @@ class FocalCurtinDisableCloudInitNetworkingVersion1( | |||
3411 | 64 | __test__ = True | 69 | __test__ = True |
3412 | 65 | 70 | ||
3413 | 66 | 71 | ||
3414 | 72 | class GroovyCurtinDisableCloudInitNetworkingVersion1( | ||
3415 | 73 | relbase.groovy, | ||
3416 | 74 | CurtinDisableCloudInitNetworkingVersion1 | ||
3417 | 75 | ): | ||
3418 | 76 | __test__ = True | ||
3419 | 77 | |||
3420 | 78 | |||
3421 | 67 | class FocalCurtinDisableCloudInitNetworking(relbase.focal, | 79 | class FocalCurtinDisableCloudInitNetworking(relbase.focal, |
3422 | 68 | CurtinDisableCloudInitNetworking): | 80 | CurtinDisableCloudInitNetworking): |
3423 | 69 | __test__ = True | 81 | __test__ = True |
3424 | 70 | 82 | ||
3425 | 71 | 83 | ||
3426 | 84 | class GroovyCurtinDisableCloudInitNetworking(relbase.groovy, | ||
3427 | 85 | CurtinDisableCloudInitNetworking): | ||
3428 | 86 | __test__ = True | ||
3429 | 87 | |||
3430 | 88 | |||
3431 | 72 | # vi: ts=4 expandtab syntax=python | 89 | # vi: ts=4 expandtab syntax=python |
3432 | diff --git a/tests/vmtests/test_network_ipv6.py b/tests/vmtests/test_network_ipv6.py | |||
3433 | index 8f0dd54..50a139c 100644 | |||
3434 | --- a/tests/vmtests/test_network_ipv6.py | |||
3435 | +++ b/tests/vmtests/test_network_ipv6.py | |||
3436 | @@ -53,9 +53,13 @@ class BionicTestNetworkIPV6(relbase.bionic, TestNetworkIPV6Abs): | |||
3437 | 53 | __test__ = True | 53 | __test__ = True |
3438 | 54 | 54 | ||
3439 | 55 | 55 | ||
3441 | 56 | class EoanTestNetworkIPV6(relbase.eoan, TestNetworkIPV6Abs): | 56 | class GroovyTestNetworkIPV6(relbase.groovy, TestNetworkIPV6Abs): |
3442 | 57 | __test__ = True | 57 | __test__ = True |
3443 | 58 | 58 | ||
3444 | 59 | @TestNetworkIPV6Abs.skip_by_date("1888726", "2020-10-15") | ||
3445 | 60 | def test_ip_output(self): | ||
3446 | 61 | return super().test_ip_output() | ||
3447 | 62 | |||
3448 | 59 | 63 | ||
3449 | 60 | class Centos66TestNetworkIPV6(centos_relbase.centos66_xenial, | 64 | class Centos66TestNetworkIPV6(centos_relbase.centos66_xenial, |
3450 | 61 | CentosTestNetworkIPV6Abs): | 65 | CentosTestNetworkIPV6Abs): |
3451 | diff --git a/tests/vmtests/test_network_ipv6_static.py b/tests/vmtests/test_network_ipv6_static.py | |||
3452 | index 8a1ba2f..28ff697 100644 | |||
3453 | --- a/tests/vmtests/test_network_ipv6_static.py | |||
3454 | +++ b/tests/vmtests/test_network_ipv6_static.py | |||
3455 | @@ -23,11 +23,11 @@ class BionicTestNetworkIPV6Static(relbase.bionic, TestNetworkIPV6StaticAbs): | |||
3456 | 23 | __test__ = True | 23 | __test__ = True |
3457 | 24 | 24 | ||
3458 | 25 | 25 | ||
3460 | 26 | class EoanTestNetworkIPV6Static(relbase.eoan, TestNetworkIPV6StaticAbs): | 26 | class FocalTestNetworkIPV6Static(relbase.focal, TestNetworkIPV6StaticAbs): |
3461 | 27 | __test__ = True | 27 | __test__ = True |
3462 | 28 | 28 | ||
3463 | 29 | 29 | ||
3465 | 30 | class FocalTestNetworkIPV6Static(relbase.focal, TestNetworkIPV6StaticAbs): | 30 | class GroovyTestNetworkIPV6Static(relbase.groovy, TestNetworkIPV6StaticAbs): |
3466 | 31 | __test__ = True | 31 | __test__ = True |
3467 | 32 | 32 | ||
3468 | 33 | 33 | ||
3469 | diff --git a/tests/vmtests/test_network_ipv6_vlan.py b/tests/vmtests/test_network_ipv6_vlan.py | |||
3470 | index 6d38621..a0bf267 100644 | |||
3471 | --- a/tests/vmtests/test_network_ipv6_vlan.py | |||
3472 | +++ b/tests/vmtests/test_network_ipv6_vlan.py | |||
3473 | @@ -22,17 +22,17 @@ class BionicTestNetworkIPV6Vlan(relbase.bionic, TestNetworkIPV6VlanAbs): | |||
3474 | 22 | __test__ = True | 22 | __test__ = True |
3475 | 23 | 23 | ||
3476 | 24 | 24 | ||
3478 | 25 | class EoanTestNetworkIPV6Vlan(relbase.eoan, TestNetworkIPV6VlanAbs): | 25 | class FocalTestNetworkIPV6Vlan(relbase.focal, TestNetworkIPV6VlanAbs): |
3479 | 26 | __test__ = True | 26 | __test__ = True |
3480 | 27 | 27 | ||
3481 | 28 | @TestNetworkVlanAbs.skip_by_date("1846232", fixby="2020-03-10") | ||
3482 | 29 | def test_ip_output(self): | ||
3483 | 30 | return super().test_ip_output() | ||
3484 | 31 | |||
3485 | 32 | 28 | ||
3487 | 33 | class FocalTestNetworkIPV6Vlan(relbase.focal, TestNetworkIPV6VlanAbs): | 29 | class GroovyTestNetworkIPV6Vlan(relbase.groovy, TestNetworkIPV6VlanAbs): |
3488 | 34 | __test__ = True | 30 | __test__ = True |
3489 | 35 | 31 | ||
3490 | 32 | @TestNetworkVlanAbs.skip_by_date("1888726", "2020-10-15") | ||
3491 | 33 | def test_ip_output(self): | ||
3492 | 34 | return super().test_ip_output() | ||
3493 | 35 | |||
3494 | 36 | 36 | ||
3495 | 37 | class Centos66TestNetworkIPV6Vlan(centos_relbase.centos66_xenial, | 37 | class Centos66TestNetworkIPV6Vlan(centos_relbase.centos66_xenial, |
3496 | 38 | CentosTestNetworkIPV6VlanAbs): | 38 | CentosTestNetworkIPV6VlanAbs): |
3497 | diff --git a/tests/vmtests/test_network_mtu.py b/tests/vmtests/test_network_mtu.py | |||
3498 | index bf13459..c70b9e0 100644 | |||
3499 | --- a/tests/vmtests/test_network_mtu.py | |||
3500 | +++ b/tests/vmtests/test_network_mtu.py | |||
3501 | @@ -137,6 +137,10 @@ class TestNetworkMtuAbs(TestNetworkIPV6Abs): | |||
3502 | 137 | self._check_iface_subnets('interface7') | 137 | self._check_iface_subnets('interface7') |
3503 | 138 | 138 | ||
3504 | 139 | 139 | ||
3505 | 140 | class TestNetworkMtuNetworkdAbs(TestNetworkMtuAbs): | ||
3506 | 141 | conf_file = "examples/tests/network_mtu_networkd.yaml" | ||
3507 | 142 | |||
3508 | 143 | |||
3509 | 140 | class CentosTestNetworkMtuAbs(TestNetworkMtuAbs): | 144 | class CentosTestNetworkMtuAbs(TestNetworkMtuAbs): |
3510 | 141 | conf_file = "examples/tests/network_mtu.yaml" | 145 | conf_file = "examples/tests/network_mtu.yaml" |
3511 | 142 | extra_collect_scripts = TestNetworkMtuAbs.extra_collect_scripts + [ | 146 | extra_collect_scripts = TestNetworkMtuAbs.extra_collect_scripts + [ |
3512 | @@ -181,28 +185,16 @@ class TestNetworkMtu(relbase.xenial, TestNetworkMtuAbs): | |||
3513 | 181 | __test__ = True | 185 | __test__ = True |
3514 | 182 | 186 | ||
3515 | 183 | 187 | ||
3518 | 184 | class BionicTestNetworkMtu(relbase.bionic, TestNetworkMtuAbs): | 188 | class BionicTestNetworkMtu(relbase.bionic, TestNetworkMtuNetworkdAbs): |
3517 | 185 | conf_file = "examples/tests/network_mtu_networkd.yaml" | ||
3519 | 186 | __test__ = True | 189 | __test__ = True |
3520 | 187 | # Until systemd is released with the fix for LP:#1671951 | ||
3521 | 188 | add_repos = "ppa:ddstreet/systemd" | ||
3522 | 189 | upgrade_packages = "cloud-init,systemd" | ||
3523 | 190 | 190 | ||
3524 | 191 | 191 | ||
3527 | 192 | class EoanTestNetworkMtu(relbase.eoan, TestNetworkMtuAbs): | 192 | class FocalTestNetworkMtu(relbase.focal, TestNetworkMtuNetworkdAbs): |
3526 | 193 | conf_file = "examples/tests/network_mtu_networkd.yaml" | ||
3528 | 194 | __test__ = True | 193 | __test__ = True |
3529 | 195 | # Until systemd is released with the fix for LP:#1671951 | ||
3530 | 196 | add_repos = "ppa:ddstreet/systemd" | ||
3531 | 197 | upgrade_packages = "cloud-init,systemd" | ||
3532 | 198 | 194 | ||
3533 | 199 | 195 | ||
3536 | 200 | class FocalTestNetworkMtu(relbase.focal, TestNetworkMtuAbs): | 196 | class GroovyTestNetworkMtu(relbase.groovy, TestNetworkMtuNetworkdAbs): |
3535 | 201 | conf_file = "examples/tests/network_mtu_networkd.yaml" | ||
3537 | 202 | __test__ = True | 197 | __test__ = True |
3538 | 203 | # Until systemd is released with the fix for LP:#1671951 | ||
3539 | 204 | add_repos = "ppa:ddstreet/systemd" | ||
3540 | 205 | upgrade_packages = "cloud-init,systemd" | ||
3541 | 206 | 198 | ||
3542 | 207 | 199 | ||
3543 | 208 | class Centos66TestNetworkMtu(centos_relbase.centos66_xenial, | 200 | class Centos66TestNetworkMtu(centos_relbase.centos66_xenial, |
3544 | diff --git a/tests/vmtests/test_network_ovs.py b/tests/vmtests/test_network_ovs.py | |||
3545 | index 3e23bd0..0cee17e 100644 | |||
3546 | --- a/tests/vmtests/test_network_ovs.py | |||
3547 | +++ b/tests/vmtests/test_network_ovs.py | |||
3548 | @@ -34,12 +34,11 @@ class BionicTestNetworkOvs(relbase.bionic, TestNetworkOvsAbs): | |||
3549 | 34 | __test__ = True | 34 | __test__ = True |
3550 | 35 | 35 | ||
3551 | 36 | 36 | ||
3553 | 37 | class EoanTestNetworkOvs(relbase.eoan, TestNetworkOvsAbs): | 37 | class FocalTestNetworkOvs(relbase.focal, TestNetworkOvsAbs): |
3554 | 38 | __test__ = True | 38 | __test__ = True |
3555 | 39 | 39 | ||
3556 | 40 | 40 | ||
3558 | 41 | class FocalTestNetworkOvs(relbase.focal, TestNetworkOvsAbs): | 41 | class GroovyTestNetworkOvs(relbase.groovy, TestNetworkOvsAbs): |
3559 | 42 | __test__ = True | 42 | __test__ = True |
3560 | 43 | 43 | ||
3561 | 44 | |||
3562 | 45 | # vi: ts=4 expandtab syntax=python | 44 | # vi: ts=4 expandtab syntax=python |
3563 | diff --git a/tests/vmtests/test_network_static.py b/tests/vmtests/test_network_static.py | |||
3564 | index 80ff2cd..e0abd54 100644 | |||
3565 | --- a/tests/vmtests/test_network_static.py | |||
3566 | +++ b/tests/vmtests/test_network_static.py | |||
3567 | @@ -28,11 +28,11 @@ class BionicTestNetworkStatic(relbase.bionic, TestNetworkStaticAbs): | |||
3568 | 28 | __test__ = True | 28 | __test__ = True |
3569 | 29 | 29 | ||
3570 | 30 | 30 | ||
3572 | 31 | class EoanTestNetworkStatic(relbase.eoan, TestNetworkStaticAbs): | 31 | class FocalTestNetworkStatic(relbase.focal, TestNetworkStaticAbs): |
3573 | 32 | __test__ = True | 32 | __test__ = True |
3574 | 33 | 33 | ||
3575 | 34 | 34 | ||
3577 | 35 | class FocalTestNetworkStatic(relbase.focal, TestNetworkStaticAbs): | 35 | class GroovyTestNetworkStatic(relbase.groovy, TestNetworkStaticAbs): |
3578 | 36 | __test__ = True | 36 | __test__ = True |
3579 | 37 | 37 | ||
3580 | 38 | 38 | ||
3581 | diff --git a/tests/vmtests/test_network_static_routes.py b/tests/vmtests/test_network_static_routes.py | |||
3582 | index dfcbffe..f99d9d5 100644 | |||
3583 | --- a/tests/vmtests/test_network_static_routes.py | |||
3584 | +++ b/tests/vmtests/test_network_static_routes.py | |||
3585 | @@ -28,13 +28,13 @@ class BionicTestNetworkStaticRoutes(relbase.bionic, | |||
3586 | 28 | __test__ = True | 28 | __test__ = True |
3587 | 29 | 29 | ||
3588 | 30 | 30 | ||
3591 | 31 | class EoanTestNetworkStaticRoutes(relbase.eoan, | 31 | class FocalTestNetworkStaticRoutes(relbase.focal, |
3592 | 32 | TestNetworkStaticRoutesAbs): | 32 | TestNetworkStaticRoutesAbs): |
3593 | 33 | __test__ = True | 33 | __test__ = True |
3594 | 34 | 34 | ||
3595 | 35 | 35 | ||
3598 | 36 | class FocalTestNetworkStaticRoutes(relbase.focal, | 36 | class GroovyTestNetworkStaticRoutes(relbase.groovy, |
3599 | 37 | TestNetworkStaticRoutesAbs): | 37 | TestNetworkStaticRoutesAbs): |
3600 | 38 | __test__ = True | 38 | __test__ = True |
3601 | 39 | 39 | ||
3602 | 40 | 40 | ||
3603 | diff --git a/tests/vmtests/test_network_vlan.py b/tests/vmtests/test_network_vlan.py | |||
3604 | index cdd06c3..9f1094b 100644 | |||
3605 | --- a/tests/vmtests/test_network_vlan.py | |||
3606 | +++ b/tests/vmtests/test_network_vlan.py | |||
3607 | @@ -76,18 +76,17 @@ class BionicTestNetworkVlan(relbase.bionic, TestNetworkVlanAbs): | |||
3608 | 76 | __test__ = True | 76 | __test__ = True |
3609 | 77 | 77 | ||
3610 | 78 | 78 | ||
3612 | 79 | class EoanTestNetworkVlan(relbase.eoan, TestNetworkVlanAbs): | 79 | class FocalTestNetworkVlan(relbase.focal, TestNetworkVlanAbs): |
3613 | 80 | __test__ = True | 80 | __test__ = True |
3614 | 81 | 81 | ||
3615 | 82 | @TestNetworkBaseTestsAbs.skip_by_date("1846232", fixby="2020-03-10") | ||
3616 | 83 | def test_ip_output(self): | 82 | def test_ip_output(self): |
3617 | 84 | return super().test_ip_output() | 83 | return super().test_ip_output() |
3618 | 85 | 84 | ||
3619 | 86 | 85 | ||
3621 | 87 | class FocalTestNetworkVlan(relbase.focal, TestNetworkVlanAbs): | 86 | class GroovyTestNetworkVlan(relbase.groovy, TestNetworkVlanAbs): |
3622 | 88 | __test__ = True | 87 | __test__ = True |
3623 | 89 | 88 | ||
3625 | 90 | @TestNetworkBaseTestsAbs.skip_by_date("1846232", fixby="2020-03-10") | 89 | @TestNetworkVlanAbs.skip_by_date("1888726", "2020-10-15") |
3626 | 91 | def test_ip_output(self): | 90 | def test_ip_output(self): |
3627 | 92 | return super().test_ip_output() | 91 | return super().test_ip_output() |
3628 | 93 | 92 | ||
3629 | diff --git a/tests/vmtests/test_nvme.py b/tests/vmtests/test_nvme.py | |||
3630 | index ca36ca8..39f9f3c 100644 | |||
3631 | --- a/tests/vmtests/test_nvme.py | |||
3632 | +++ b/tests/vmtests/test_nvme.py | |||
3633 | @@ -73,7 +73,7 @@ class BionicTestNvme(relbase.bionic, TestNvmeAbs): | |||
3634 | 73 | __test__ = True | 73 | __test__ = True |
3635 | 74 | 74 | ||
3636 | 75 | 75 | ||
3638 | 76 | class EoanTestNvme(relbase.eoan, TestNvmeAbs): | 76 | class GroovyTestNvme(relbase.groovy, TestNvmeAbs): |
3639 | 77 | __test__ = True | 77 | __test__ = True |
3640 | 78 | 78 | ||
3641 | 79 | 79 | ||
3642 | @@ -139,12 +139,11 @@ class BionicTestNvmeBcache(relbase.bionic, TestNvmeBcacheAbs): | |||
3643 | 139 | __test__ = True | 139 | __test__ = True |
3644 | 140 | 140 | ||
3645 | 141 | 141 | ||
3647 | 142 | class EoanTestNvmeBcache(relbase.eoan, TestNvmeBcacheAbs): | 142 | class FocalTestNvmeBcache(relbase.focal, TestNvmeBcacheAbs): |
3648 | 143 | __test__ = True | 143 | __test__ = True |
3649 | 144 | 144 | ||
3650 | 145 | 145 | ||
3653 | 146 | @TestNvmeBcacheAbs.skip_by_date("1861941", fixby="2020-04-15") | 146 | class GroovyTestNvmeBcache(relbase.groovy, TestNvmeBcacheAbs): |
3652 | 147 | class FocalTestNvmeBcache(relbase.focal, TestNvmeBcacheAbs): | ||
3654 | 148 | __test__ = True | 147 | __test__ = True |
3655 | 149 | 148 | ||
3656 | 150 | 149 | ||
3657 | diff --git a/tests/vmtests/test_panic.py b/tests/vmtests/test_panic.py | |||
3658 | index fe4005e..7b1fdbe 100644 | |||
3659 | --- a/tests/vmtests/test_panic.py | |||
3660 | +++ b/tests/vmtests/test_panic.py | |||
3661 | @@ -28,4 +28,9 @@ class TestInstallPanic(VMBaseClass): | |||
3662 | 28 | class FocalTestInstallPanic(relbase.focal, TestInstallPanic): | 28 | class FocalTestInstallPanic(relbase.focal, TestInstallPanic): |
3663 | 29 | __test__ = True | 29 | __test__ = True |
3664 | 30 | 30 | ||
3665 | 31 | |||
3666 | 32 | class GroovyTestInstallPanic(relbase.groovy, TestInstallPanic): | ||
3667 | 33 | __test__ = True | ||
3668 | 34 | |||
3669 | 35 | |||
3670 | 31 | # vi: ts=4 expandtab syntax=python | 36 | # vi: ts=4 expandtab syntax=python |
3671 | diff --git a/tests/vmtests/test_pollinate_useragent.py b/tests/vmtests/test_pollinate_useragent.py | |||
3672 | index ff21f20..ed14719 100644 | |||
3673 | --- a/tests/vmtests/test_pollinate_useragent.py | |||
3674 | +++ b/tests/vmtests/test_pollinate_useragent.py | |||
3675 | @@ -61,11 +61,11 @@ class BionicTestPollinateUserAgent(relbase.bionic, TestPollinateUserAgent): | |||
3676 | 61 | __test__ = True | 61 | __test__ = True |
3677 | 62 | 62 | ||
3678 | 63 | 63 | ||
3680 | 64 | class EoanTestPollinateUserAgent(relbase.eoan, TestPollinateUserAgent): | 64 | class FocalTestPollinateUserAgent(relbase.focal, TestPollinateUserAgent): |
3681 | 65 | __test__ = True | 65 | __test__ = True |
3682 | 66 | 66 | ||
3683 | 67 | 67 | ||
3685 | 68 | class FocalTestPollinateUserAgent(relbase.focal, TestPollinateUserAgent): | 68 | class GroovyTestPollinateUserAgent(relbase.groovy, TestPollinateUserAgent): |
3686 | 69 | __test__ = True | 69 | __test__ = True |
3687 | 70 | 70 | ||
3688 | 71 | 71 | ||
3689 | diff --git a/tests/vmtests/test_preserve.py b/tests/vmtests/test_preserve.py | |||
3690 | index f02ba6c..998218c 100644 | |||
3691 | --- a/tests/vmtests/test_preserve.py | |||
3692 | +++ b/tests/vmtests/test_preserve.py | |||
3693 | @@ -25,11 +25,11 @@ class BionicTestPreserve(relbase.bionic, TestPreserve): | |||
3694 | 25 | __test__ = True | 25 | __test__ = True |
3695 | 26 | 26 | ||
3696 | 27 | 27 | ||
3698 | 28 | class EoanTestPreserve(relbase.eoan, TestPreserve): | 28 | class FocalTestPreserve(relbase.focal, TestPreserve): |
3699 | 29 | __test__ = True | 29 | __test__ = True |
3700 | 30 | 30 | ||
3701 | 31 | 31 | ||
3703 | 32 | class FocalTestPreserve(relbase.focal, TestPreserve): | 32 | class GroovyTestPreserve(relbase.groovy, TestPreserve): |
3704 | 33 | __test__ = True | 33 | __test__ = True |
3705 | 34 | 34 | ||
3706 | 35 | 35 | ||
3707 | diff --git a/tests/vmtests/test_preserve_bcache.py b/tests/vmtests/test_preserve_bcache.py | |||
3708 | index e2d2a34..bd91c5a 100644 | |||
3709 | --- a/tests/vmtests/test_preserve_bcache.py | |||
3710 | +++ b/tests/vmtests/test_preserve_bcache.py | |||
3711 | @@ -56,11 +56,11 @@ class BionicTestPreserveBcache(relbase.bionic, TestPreserveBcache): | |||
3712 | 56 | __test__ = True | 56 | __test__ = True |
3713 | 57 | 57 | ||
3714 | 58 | 58 | ||
3716 | 59 | class EoanTestPreserveBcache(relbase.eoan, TestPreserveBcache): | 59 | class FocalTestPreserveBcache(relbase.focal, TestPreserveBcache): |
3717 | 60 | __test__ = True | 60 | __test__ = True |
3718 | 61 | 61 | ||
3719 | 62 | 62 | ||
3721 | 63 | class FocalTestPreserveBcache(relbase.focal, TestPreserveBcache): | 63 | class GroovyTestPreserveBcache(relbase.groovy, TestPreserveBcache): |
3722 | 64 | __test__ = True | 64 | __test__ = True |
3723 | 65 | 65 | ||
3724 | 66 | 66 | ||
3725 | diff --git a/tests/vmtests/test_preserve_lvm.py b/tests/vmtests/test_preserve_lvm.py | |||
3726 | index 90f15cb..0ed7ad4 100644 | |||
3727 | --- a/tests/vmtests/test_preserve_lvm.py | |||
3728 | +++ b/tests/vmtests/test_preserve_lvm.py | |||
3729 | @@ -69,11 +69,11 @@ class BionicTestLvmPreserve(relbase.bionic, TestLvmPreserveAbs): | |||
3730 | 69 | __test__ = True | 69 | __test__ = True |
3731 | 70 | 70 | ||
3732 | 71 | 71 | ||
3734 | 72 | class EoanTestLvmPreserve(relbase.eoan, TestLvmPreserveAbs): | 72 | class FocalTestLvmPreserve(relbase.focal, TestLvmPreserveAbs): |
3735 | 73 | __test__ = True | 73 | __test__ = True |
3736 | 74 | 74 | ||
3737 | 75 | 75 | ||
3739 | 76 | class FocalTestLvmPreserve(relbase.focal, TestLvmPreserveAbs): | 76 | class GroovyTestLvmPreserve(relbase.groovy, TestLvmPreserveAbs): |
3740 | 77 | __test__ = True | 77 | __test__ = True |
3741 | 78 | 78 | ||
3742 | 79 | 79 | ||
3743 | diff --git a/tests/vmtests/test_preserve_partition_wipe_vg.py b/tests/vmtests/test_preserve_partition_wipe_vg.py | |||
3744 | index 96346ff..58b1f65 100644 | |||
3745 | --- a/tests/vmtests/test_preserve_partition_wipe_vg.py | |||
3746 | +++ b/tests/vmtests/test_preserve_partition_wipe_vg.py | |||
3747 | @@ -25,11 +25,11 @@ class BionicTestPreserveWipeLvm(relbase.bionic, TestPreserveWipeLvm): | |||
3748 | 25 | __test__ = True | 25 | __test__ = True |
3749 | 26 | 26 | ||
3750 | 27 | 27 | ||
3752 | 28 | class EoanTestPreserveWipeLvm(relbase.eoan, TestPreserveWipeLvm): | 28 | class FocalTestPreserveWipeLvm(relbase.focal, TestPreserveWipeLvm): |
3753 | 29 | __test__ = True | 29 | __test__ = True |
3754 | 30 | 30 | ||
3755 | 31 | 31 | ||
3757 | 32 | class FocalTestPreserveWipeLvm(relbase.focal, TestPreserveWipeLvm): | 32 | class GroovyTestPreserveWipeLvm(relbase.groovy, TestPreserveWipeLvm): |
3758 | 33 | __test__ = True | 33 | __test__ = True |
3759 | 34 | 34 | ||
3760 | 35 | 35 | ||
3761 | @@ -48,11 +48,12 @@ class BionicTestPreserveWipeLvmSimple(relbase.bionic, | |||
3762 | 48 | __test__ = True | 48 | __test__ = True |
3763 | 49 | 49 | ||
3764 | 50 | 50 | ||
3766 | 51 | class EoanTestPreserveWipeLvmSimple(relbase.eoan, TestPreserveWipeLvmSimple): | 51 | class FocalTestPreserveWipeLvmSimple(relbase.focal, TestPreserveWipeLvmSimple): |
3767 | 52 | __test__ = True | 52 | __test__ = True |
3768 | 53 | 53 | ||
3769 | 54 | 54 | ||
3771 | 55 | class FocalTestPreserveWipeLvmSimple(relbase.focal, TestPreserveWipeLvmSimple): | 55 | class GroovyTestPreserveWipeLvmSimple(relbase.groovy, |
3772 | 56 | TestPreserveWipeLvmSimple): | ||
3773 | 56 | __test__ = True | 57 | __test__ = True |
3774 | 57 | 58 | ||
3775 | 58 | 59 | ||
3776 | diff --git a/tests/vmtests/test_preserve_raid.py b/tests/vmtests/test_preserve_raid.py | |||
3777 | index cf3a6bb..15f2f50 100644 | |||
3778 | --- a/tests/vmtests/test_preserve_raid.py | |||
3779 | +++ b/tests/vmtests/test_preserve_raid.py | |||
3780 | @@ -25,11 +25,11 @@ class BionicTestPreserveRAID(relbase.bionic, TestPreserveRAID): | |||
3781 | 25 | __test__ = True | 25 | __test__ = True |
3782 | 26 | 26 | ||
3783 | 27 | 27 | ||
3785 | 28 | class EoanTestPreserveRAID(relbase.eoan, TestPreserveRAID): | 28 | class FocalTestPreserveRAID(relbase.focal, TestPreserveRAID): |
3786 | 29 | __test__ = True | 29 | __test__ = True |
3787 | 30 | 30 | ||
3788 | 31 | 31 | ||
3790 | 32 | class FocalTestPreserveRAID(relbase.focal, TestPreserveRAID): | 32 | class GroovyTestPreserveRAID(relbase.groovy, TestPreserveRAID): |
3791 | 33 | __test__ = True | 33 | __test__ = True |
3792 | 34 | 34 | ||
3793 | 35 | 35 | ||
3794 | diff --git a/tests/vmtests/test_raid5_bcache.py b/tests/vmtests/test_raid5_bcache.py | |||
3795 | index 7138a2c..3fdb217 100644 | |||
3796 | --- a/tests/vmtests/test_raid5_bcache.py | |||
3797 | +++ b/tests/vmtests/test_raid5_bcache.py | |||
3798 | @@ -88,16 +88,16 @@ class BionicTestRaid5Bcache(relbase.bionic, TestMdadmBcacheAbs): | |||
3799 | 88 | __test__ = True | 88 | __test__ = True |
3800 | 89 | 89 | ||
3801 | 90 | 90 | ||
3802 | 91 | class EoanTestRaid5Bcache(relbase.eoan, TestMdadmBcacheAbs): | ||
3803 | 92 | __test__ = True | ||
3804 | 93 | |||
3805 | 94 | |||
3806 | 95 | class FocalTestRaid5Bcache(relbase.focal, TestMdadmBcacheAbs): | 91 | class FocalTestRaid5Bcache(relbase.focal, TestMdadmBcacheAbs): |
3807 | 96 | __test__ = True | 92 | __test__ = True |
3808 | 97 | 93 | ||
3810 | 98 | @TestMdadmBcacheAbs.skip_by_date("1861941", fixby="2020-04-15") | 94 | @TestMdadmBcacheAbs.skip_by_date("1861941", fixby="2020-09-15") |
3811 | 99 | def test_fstab(self): | 95 | def test_fstab(self): |
3812 | 100 | return super().test_fstab() | 96 | return super().test_fstab() |
3813 | 101 | 97 | ||
3814 | 102 | 98 | ||
3815 | 99 | class GroovyTestRaid5Bcache(relbase.groovy, TestMdadmBcacheAbs): | ||
3816 | 100 | __test__ = True | ||
3817 | 101 | |||
3818 | 102 | |||
3819 | 103 | # vi: ts=4 expandtab syntax=python | 103 | # vi: ts=4 expandtab syntax=python |
3820 | diff --git a/tests/vmtests/test_reuse_lvm_member.py b/tests/vmtests/test_reuse_lvm_member.py | |||
3821 | index 749ea24..87afcfb 100644 | |||
3822 | --- a/tests/vmtests/test_reuse_lvm_member.py | |||
3823 | +++ b/tests/vmtests/test_reuse_lvm_member.py | |||
3824 | @@ -21,13 +21,13 @@ class BionicTestReuseLVMMemberPartition(relbase.bionic, | |||
3825 | 21 | __test__ = True | 21 | __test__ = True |
3826 | 22 | 22 | ||
3827 | 23 | 23 | ||
3830 | 24 | class EoanTestReuseLVMMemberPartition(relbase.eoan, | 24 | class FocalTestReuseLVMMemberPartition(relbase.focal, |
3831 | 25 | TestReuseLVMMemberPartition): | 25 | TestReuseLVMMemberPartition): |
3832 | 26 | __test__ = True | 26 | __test__ = True |
3833 | 27 | 27 | ||
3834 | 28 | 28 | ||
3837 | 29 | class FocalTestReuseLVMMemberPartition(relbase.focal, | 29 | class GroovyTestReuseLVMMemberPartition(relbase.groovy, |
3838 | 30 | TestReuseLVMMemberPartition): | 30 | TestReuseLVMMemberPartition): |
3839 | 31 | __test__ = True | 31 | __test__ = True |
3840 | 32 | 32 | ||
3841 | 33 | 33 | ||
3842 | diff --git a/tests/vmtests/test_reuse_msdos_partitions.py b/tests/vmtests/test_reuse_msdos_partitions.py | |||
3843 | index f8e20d9..9f18d3c 100644 | |||
3844 | --- a/tests/vmtests/test_reuse_msdos_partitions.py | |||
3845 | +++ b/tests/vmtests/test_reuse_msdos_partitions.py | |||
3846 | @@ -18,13 +18,13 @@ class BionicTestReuseMSDOSPartitions(relbase.bionic, | |||
3847 | 18 | __test__ = True | 18 | __test__ = True |
3848 | 19 | 19 | ||
3849 | 20 | 20 | ||
3852 | 21 | class EoanTestReuseMSDOSPartitions(relbase.eoan, | 21 | class FocalTestReuseMSDOSPartitions(relbase.focal, |
3853 | 22 | TestReuseMSDOSPartitions): | 22 | TestReuseMSDOSPartitions): |
3854 | 23 | __test__ = True | 23 | __test__ = True |
3855 | 24 | 24 | ||
3856 | 25 | 25 | ||
3859 | 26 | class FocalTestReuseMSDOSPartitions(relbase.focal, | 26 | class GroovyTestReuseMSDOSPartitions(relbase.groovy, |
3860 | 27 | TestReuseMSDOSPartitions): | 27 | TestReuseMSDOSPartitions): |
3861 | 28 | __test__ = True | 28 | __test__ = True |
3862 | 29 | 29 | ||
3863 | 30 | 30 | ||
3864 | diff --git a/tests/vmtests/test_reuse_raid_member.py b/tests/vmtests/test_reuse_raid_member.py | |||
3865 | index 425105f..7be98f3 100644 | |||
3866 | --- a/tests/vmtests/test_reuse_raid_member.py | |||
3867 | +++ b/tests/vmtests/test_reuse_raid_member.py | |||
3868 | @@ -28,11 +28,11 @@ class BionicTestReuseRAIDMember(relbase.bionic, TestReuseRAIDMember): | |||
3869 | 28 | __test__ = True | 28 | __test__ = True |
3870 | 29 | 29 | ||
3871 | 30 | 30 | ||
3873 | 31 | class EoanTestReuseRAIDMember(relbase.eoan, TestReuseRAIDMember): | 31 | class FocalTestReuseRAIDMember(relbase.focal, TestReuseRAIDMember): |
3874 | 32 | __test__ = True | 32 | __test__ = True |
3875 | 33 | 33 | ||
3876 | 34 | 34 | ||
3878 | 35 | class FocalTestReuseRAIDMember(relbase.focal, TestReuseRAIDMember): | 35 | class GroovyTestReuseRAIDMember(relbase.groovy, TestReuseRAIDMember): |
3879 | 36 | __test__ = True | 36 | __test__ = True |
3880 | 37 | 37 | ||
3881 | 38 | 38 | ||
3882 | @@ -41,13 +41,13 @@ class BionicTestReuseRAIDMemberPartition(relbase.bionic, | |||
3883 | 41 | __test__ = True | 41 | __test__ = True |
3884 | 42 | 42 | ||
3885 | 43 | 43 | ||
3888 | 44 | class EoanTestReuseRAIDMemberPartition(relbase.eoan, | 44 | class FocalTestReuseRAIDMemberPartition(relbase.focal, |
3889 | 45 | TestReuseRAIDMemberPartition): | 45 | TestReuseRAIDMemberPartition): |
3890 | 46 | __test__ = True | 46 | __test__ = True |
3891 | 47 | 47 | ||
3892 | 48 | 48 | ||
3895 | 49 | class FocalTestReuseRAIDMemberPartition(relbase.focal, | 49 | class GroovyTestReuseRAIDMemberPartition(relbase.groovy, |
3896 | 50 | TestReuseRAIDMemberPartition): | 50 | TestReuseRAIDMemberPartition): |
3897 | 51 | __test__ = True | 51 | __test__ = True |
3898 | 52 | 52 | ||
3899 | 53 | 53 | ||
3900 | diff --git a/tests/vmtests/test_reuse_uefi_esp.py b/tests/vmtests/test_reuse_uefi_esp.py | |||
3901 | index 1e99935..46e7ac7 100644 | |||
3902 | --- a/tests/vmtests/test_reuse_uefi_esp.py | |||
3903 | +++ b/tests/vmtests/test_reuse_uefi_esp.py | |||
3904 | @@ -3,17 +3,20 @@ | |||
3905 | 3 | from .test_uefi_basic import TestBasicAbs | 3 | from .test_uefi_basic import TestBasicAbs |
3906 | 4 | from .releases import base_vm_classes as relbase | 4 | from .releases import base_vm_classes as relbase |
3907 | 5 | from .releases import centos_base_vm_classes as cent_rbase | 5 | from .releases import centos_base_vm_classes as cent_rbase |
3908 | 6 | from curtin.commands.curthooks import uefi_find_duplicate_entries | ||
3909 | 7 | from curtin import util | ||
3910 | 6 | 8 | ||
3911 | 7 | 9 | ||
3912 | 8 | class TestUefiReuseEspAbs(TestBasicAbs): | 10 | class TestUefiReuseEspAbs(TestBasicAbs): |
3913 | 9 | conf_file = "examples/tests/uefi_reuse_esp.yaml" | 11 | conf_file = "examples/tests/uefi_reuse_esp.yaml" |
3914 | 10 | 12 | ||
3915 | 11 | def test_efiboot_menu_has_one_distro_entry(self): | 13 | def test_efiboot_menu_has_one_distro_entry(self): |
3921 | 12 | efiboot_mgr_content = self.load_collect_file("efibootmgr.out") | 14 | efi_output = util.parse_efibootmgr( |
3922 | 13 | distro_lines = [line for line in efiboot_mgr_content.splitlines() | 15 | self.load_collect_file("efibootmgr.out")) |
3923 | 14 | if self.target_distro in line] | 16 | duplicates = uefi_find_duplicate_entries( |
3924 | 15 | print(distro_lines) | 17 | grubcfg=None, target=None, efi_output=efi_output) |
3925 | 16 | self.assertEqual(1, len(distro_lines)) | 18 | print(duplicates) |
3926 | 19 | self.assertEqual(0, len(duplicates)) | ||
3927 | 17 | 20 | ||
3928 | 18 | 21 | ||
3929 | 19 | class Cent70TestUefiReuseEsp(cent_rbase.centos70_bionic, TestUefiReuseEspAbs): | 22 | class Cent70TestUefiReuseEsp(cent_rbase.centos70_bionic, TestUefiReuseEspAbs): |
3930 | @@ -28,23 +31,20 @@ class XenialGATestUefiReuseEsp(relbase.xenial_ga, TestUefiReuseEspAbs): | |||
3931 | 28 | class BionicTestUefiReuseEsp(relbase.bionic, TestUefiReuseEspAbs): | 31 | class BionicTestUefiReuseEsp(relbase.bionic, TestUefiReuseEspAbs): |
3932 | 29 | __test__ = True | 32 | __test__ = True |
3933 | 30 | 33 | ||
3934 | 31 | @TestUefiReuseEspAbs.skip_by_date("1863015", fixby="2020-04-15") | ||
3935 | 32 | def test_efiboot_menu_has_one_distro_entry(self): | 34 | def test_efiboot_menu_has_one_distro_entry(self): |
3936 | 33 | return super().test_efiboot_menu_has_one_distro_entry() | 35 | return super().test_efiboot_menu_has_one_distro_entry() |
3937 | 34 | 36 | ||
3938 | 35 | 37 | ||
3940 | 36 | class EoanTestUefiReuseEsp(relbase.eoan, TestUefiReuseEspAbs): | 38 | class FocalTestUefiReuseEsp(relbase.focal, TestUefiReuseEspAbs): |
3941 | 37 | __test__ = True | 39 | __test__ = True |
3942 | 38 | 40 | ||
3943 | 39 | @TestUefiReuseEspAbs.skip_by_date("1863015", fixby="2020-04-15") | ||
3944 | 40 | def test_efiboot_menu_has_one_distro_entry(self): | 41 | def test_efiboot_menu_has_one_distro_entry(self): |
3945 | 41 | return super().test_efiboot_menu_has_one_distro_entry() | 42 | return super().test_efiboot_menu_has_one_distro_entry() |
3946 | 42 | 43 | ||
3947 | 43 | 44 | ||
3949 | 44 | class FocalTestUefiReuseEsp(relbase.focal, TestUefiReuseEspAbs): | 45 | class GroovyTestUefiReuseEsp(relbase.groovy, TestUefiReuseEspAbs): |
3950 | 45 | __test__ = True | 46 | __test__ = True |
3951 | 46 | 47 | ||
3952 | 47 | @TestUefiReuseEspAbs.skip_by_date("1863015", fixby="2020-04-15") | ||
3953 | 48 | def test_efiboot_menu_has_one_distro_entry(self): | 48 | def test_efiboot_menu_has_one_distro_entry(self): |
3954 | 49 | return super().test_efiboot_menu_has_one_distro_entry() | 49 | return super().test_efiboot_menu_has_one_distro_entry() |
3955 | 50 | 50 | ||
3956 | diff --git a/tests/vmtests/test_simple.py b/tests/vmtests/test_simple.py | |||
3957 | index b34a6fc..9e71047 100644 | |||
3958 | --- a/tests/vmtests/test_simple.py | |||
3959 | +++ b/tests/vmtests/test_simple.py | |||
3960 | @@ -49,14 +49,14 @@ class BionicTestSimple(relbase.bionic, TestSimple): | |||
3961 | 49 | self.output_files_exist(["netplan.yaml"]) | 49 | self.output_files_exist(["netplan.yaml"]) |
3962 | 50 | 50 | ||
3963 | 51 | 51 | ||
3965 | 52 | class EoanTestSimple(relbase.eoan, TestSimple): | 52 | class FocalTestSimple(relbase.focal, TestSimple): |
3966 | 53 | __test__ = True | 53 | __test__ = True |
3967 | 54 | 54 | ||
3968 | 55 | def test_output_files_exist(self): | 55 | def test_output_files_exist(self): |
3969 | 56 | self.output_files_exist(["netplan.yaml"]) | 56 | self.output_files_exist(["netplan.yaml"]) |
3970 | 57 | 57 | ||
3971 | 58 | 58 | ||
3973 | 59 | class FocalTestSimple(relbase.focal, TestSimple): | 59 | class GroovyTestSimple(relbase.groovy, TestSimple): |
3974 | 60 | __test__ = True | 60 | __test__ = True |
3975 | 61 | 61 | ||
3976 | 62 | def test_output_files_exist(self): | 62 | def test_output_files_exist(self): |
3977 | @@ -105,14 +105,14 @@ class BionicTestSimpleStorage(relbase.bionic, TestSimpleStorage): | |||
3978 | 105 | self.output_files_exist(["netplan.yaml"]) | 105 | self.output_files_exist(["netplan.yaml"]) |
3979 | 106 | 106 | ||
3980 | 107 | 107 | ||
3982 | 108 | class EoanTestSimpleStorage(relbase.eoan, TestSimpleStorage): | 108 | class FocalTestSimpleStorage(relbase.focal, TestSimpleStorage): |
3983 | 109 | __test__ = True | 109 | __test__ = True |
3984 | 110 | 110 | ||
3985 | 111 | def test_output_files_exist(self): | 111 | def test_output_files_exist(self): |
3986 | 112 | self.output_files_exist(["netplan.yaml"]) | 112 | self.output_files_exist(["netplan.yaml"]) |
3987 | 113 | 113 | ||
3988 | 114 | 114 | ||
3990 | 115 | class FocalTestSimpleStorage(relbase.focal, TestSimpleStorage): | 115 | class GroovyTestSimpleStorage(relbase.groovy, TestSimpleStorage): |
3991 | 116 | __test__ = True | 116 | __test__ = True |
3992 | 117 | 117 | ||
3993 | 118 | def test_output_files_exist(self): | 118 | def test_output_files_exist(self): |
3994 | @@ -145,4 +145,11 @@ class FocalTestGrubNoDefaults(relbase.focal, TestGrubNoDefaults): | |||
3995 | 145 | self.output_files_exist(["netplan.yaml"]) | 145 | self.output_files_exist(["netplan.yaml"]) |
3996 | 146 | 146 | ||
3997 | 147 | 147 | ||
3998 | 148 | class GroovyTestGrubNoDefaults(relbase.groovy, TestGrubNoDefaults): | ||
3999 | 149 | __test__ = True | ||
4000 | 150 | |||
4001 | 151 | def test_output_files_exist(self): | ||
4002 | 152 | self.output_files_exist(["netplan.yaml"]) | ||
4003 | 153 | |||
4004 | 154 | |||
4005 | 148 | # vi: ts=4 expandtab syntax=python | 155 | # vi: ts=4 expandtab syntax=python |
4006 | diff --git a/tests/vmtests/test_uefi_basic.py b/tests/vmtests/test_uefi_basic.py | |||
4007 | index 90940dd..932c1c8 100644 | |||
4008 | --- a/tests/vmtests/test_uefi_basic.py | |||
4009 | +++ b/tests/vmtests/test_uefi_basic.py | |||
4010 | @@ -89,6 +89,11 @@ class PreciseHWETUefiTestBasic(relbase.precise_hwe_t, PreciseUefiTestBasic): | |||
4011 | 89 | __test__ = False | 89 | __test__ = False |
4012 | 90 | 90 | ||
4013 | 91 | 91 | ||
4014 | 92 | class TrustyHWEXUefiTestBasic(relbase.trusty_hwe_x, TestBasicAbs): | ||
4015 | 93 | supported_releases = ['trusty'] # avoid unsupported release skiptest | ||
4016 | 94 | __test__ = False | ||
4017 | 95 | |||
4018 | 96 | |||
4019 | 92 | class XenialGAUefiTestBasic(relbase.xenial_ga, TestBasicAbs): | 97 | class XenialGAUefiTestBasic(relbase.xenial_ga, TestBasicAbs): |
4020 | 93 | __test__ = True | 98 | __test__ = True |
4021 | 94 | 99 | ||
4022 | @@ -105,11 +110,11 @@ class BionicUefiTestBasic(relbase.bionic, TestBasicAbs): | |||
4023 | 105 | __test__ = True | 110 | __test__ = True |
4024 | 106 | 111 | ||
4025 | 107 | 112 | ||
4027 | 108 | class EoanUefiTestBasic(relbase.eoan, TestBasicAbs): | 113 | class FocalUefiTestBasic(relbase.focal, TestBasicAbs): |
4028 | 109 | __test__ = True | 114 | __test__ = True |
4029 | 110 | 115 | ||
4030 | 111 | 116 | ||
4032 | 112 | class FocalUefiTestBasic(relbase.focal, TestBasicAbs): | 117 | class GroovyUefiTestBasic(relbase.groovy, TestBasicAbs): |
4033 | 113 | __test__ = True | 118 | __test__ = True |
4034 | 114 | 119 | ||
4035 | 115 | 120 | ||
4036 | @@ -128,12 +133,12 @@ class BionicUefiTestBasic4k(relbase.bionic, TestBasicAbs): | |||
4037 | 128 | disk_block_size = 4096 | 133 | disk_block_size = 4096 |
4038 | 129 | 134 | ||
4039 | 130 | 135 | ||
4041 | 131 | class EoanUefiTestBasic4k(relbase.eoan, TestBasicAbs): | 136 | class FocalUefiTestBasic4k(relbase.focal, TestBasicAbs): |
4042 | 132 | __test__ = True | 137 | __test__ = True |
4043 | 133 | disk_block_size = 4096 | 138 | disk_block_size = 4096 |
4044 | 134 | 139 | ||
4045 | 135 | 140 | ||
4047 | 136 | class FocalUefiTestBasic4k(relbase.focal, TestBasicAbs): | 141 | class GroovyUefiTestBasic4k(relbase.groovy, TestBasicAbs): |
4048 | 137 | __test__ = True | 142 | __test__ = True |
4049 | 138 | disk_block_size = 4096 | 143 | disk_block_size = 4096 |
4050 | 139 | 144 | ||
4051 | diff --git a/tests/vmtests/test_zfsroot.py b/tests/vmtests/test_zfsroot.py | |||
4052 | index c9c73a3..952bf7b 100644 | |||
4053 | --- a/tests/vmtests/test_zfsroot.py | |||
4054 | +++ b/tests/vmtests/test_zfsroot.py | |||
4055 | @@ -96,12 +96,12 @@ class BionicTestZfsRoot(relbase.bionic, TestZfsRootAbs): | |||
4056 | 96 | __test__ = True | 96 | __test__ = True |
4057 | 97 | 97 | ||
4058 | 98 | 98 | ||
4060 | 99 | class EoanTestZfsRoot(relbase.eoan, TestZfsRootAbs): | 99 | class FocalTestZfsRoot(relbase.focal, TestZfsRootAbs): |
4061 | 100 | __test__ = True | 100 | __test__ = True |
4062 | 101 | mem = 4096 | 101 | mem = 4096 |
4063 | 102 | 102 | ||
4064 | 103 | 103 | ||
4066 | 104 | class FocalTestZfsRoot(relbase.focal, TestZfsRootAbs): | 104 | class GroovyTestZfsRoot(relbase.groovy, TestZfsRootAbs): |
4067 | 105 | __test__ = True | 105 | __test__ = True |
4068 | 106 | mem = 4096 | 106 | mem = 4096 |
4069 | 107 | 107 | ||
4070 | @@ -125,13 +125,12 @@ class BionicTestZfsRootFsType(relbase.bionic, TestZfsRootFsTypeAbs): | |||
4071 | 125 | __test__ = True | 125 | __test__ = True |
4072 | 126 | 126 | ||
4073 | 127 | 127 | ||
4075 | 128 | class EoanTestZfsRootFsType(relbase.eoan, TestZfsRootFsTypeAbs): | 128 | class FocalTestZfsRootFsType(relbase.focal, TestZfsRootFsTypeAbs): |
4076 | 129 | __test__ = True | 129 | __test__ = True |
4077 | 130 | mem = 4096 | 130 | mem = 4096 |
4078 | 131 | 131 | ||
4079 | 132 | 132 | ||
4081 | 133 | class FocalTestZfsRootFsType(relbase.focal, TestZfsRootFsTypeAbs): | 133 | class GroovyTestZfsRootFsType(relbase.groovy, TestZfsRootFsTypeAbs): |
4082 | 134 | __test__ = True | 134 | __test__ = True |
4083 | 135 | mem = 4096 | ||
4084 | 136 | 135 | ||
4085 | 137 | # vi: ts=4 expandtab syntax=python | 136 | # vi: ts=4 expandtab syntax=python |
4086 | diff --git a/tools/curtainer b/tools/curtainer | |||
4087 | index 466d719..b24884b 100755 | |||
4088 | --- a/tools/curtainer | |||
4089 | +++ b/tools/curtainer | |||
4090 | @@ -153,20 +153,35 @@ main() { | |||
4091 | 153 | fi | 153 | fi |
4092 | 154 | getsource="${getsource%/}" | 154 | getsource="${getsource%/}" |
4093 | 155 | 155 | ||
4095 | 156 | lxc launch "$src" "$name" || fail "failed lxc launch $src $name" | 156 | # launch container; mask snapd.seeded.service; not needed |
4096 | 157 | { | ||
4097 | 158 | lxc init "$src" "$name" && | ||
4098 | 159 | lxc file push \ | ||
4099 | 160 | /dev/null ${name}/etc/systemd/system/snapd.seeded.service && | ||
4100 | 161 | lxc start ${name} | ||
4101 | 162 | } || fail "failed lxc launch $src $name" | ||
4102 | 157 | CONTAINER=$name | 163 | CONTAINER=$name |
4103 | 158 | 164 | ||
4104 | 159 | wait_for_ready "$name" $maxwait $VERBOSITY || | 165 | wait_for_ready "$name" $maxwait $VERBOSITY || |
4105 | 160 | fail "$name did not become ready after $maxwait" | 166 | fail "$name did not become ready after $maxwait" |
4106 | 161 | 167 | ||
4107 | 162 | inside "$name" which eatmydata >/dev/null || eatmydata="" | 168 | inside "$name" which eatmydata >/dev/null || eatmydata="" |
4108 | 169 | release=$(inside $name lsb_release -sc) || | ||
4109 | 170 | fail "$name did not have a lsb release codename" | ||
4110 | 171 | |||
4111 | 172 | # curtin depends on zfsutils-linux via probert-storage, but zfsutils-linux | ||
4112 | 173 | # can't be installed in an unprivileged container as it fails to start | ||
4113 | 174 | # the zfs-mount and zfs-share services as /dev/zfs is missing. We do | ||
4114 | 175 | # not actually need ZFS to work in the container, so the problem can be | ||
4115 | 176 | # worked around by masking the services before the package is installed. | ||
4116 | 177 | inside "$name" systemctl mask zfs-mount || fail "failed to mask zfs-mount" | ||
4117 | 178 | inside "$name" systemctl mask zfs-share || fail "failed to mask zfs-share" | ||
4118 | 163 | 179 | ||
4119 | 164 | if $proposed; then | 180 | if $proposed; then |
4120 | 165 | mirror=$(inside $name awk '$1 == "deb" { print $2; exit(0); }' \ | 181 | mirror=$(inside $name awk '$1 == "deb" { print $2; exit(0); }' \ |
4123 | 166 | /etc/apt/sources.list) && | 182 | /etc/apt/sources.list) || |
4122 | 167 | rel=$(inside $name lsb_release -sc) || | ||
4124 | 168 | fail "failed to get mirror in $name" | 183 | fail "failed to get mirror in $name" |
4126 | 169 | line="$mirror $rel-proposed main universe" | 184 | line="$mirror $release-proposed main universe" |
4127 | 170 | local fname="/etc/apt/sources.list.d/proposed.list" | 185 | local fname="/etc/apt/sources.list.d/proposed.list" |
4128 | 171 | debug 1 "enabling proposed in $fname: deb $line" | 186 | debug 1 "enabling proposed in $fname: deb $line" |
4129 | 172 | inside "$name" sh -c "echo deb $line > $fname" || | 187 | inside "$name" sh -c "echo deb $line > $fname" || |
4130 | @@ -179,9 +194,30 @@ main() { | |||
4131 | 179 | if $daily; then | 194 | if $daily; then |
4132 | 180 | local daily_ppa="ppa:curtin-dev/daily" | 195 | local daily_ppa="ppa:curtin-dev/daily" |
4133 | 181 | debug 1 "enabling daily: $daily_ppa" | 196 | debug 1 "enabling daily: $daily_ppa" |
4137 | 182 | inside "$name" add-apt-repository --enable-source --yes \ | 197 | local addaptrepo="add-apt-repository" |
4138 | 183 | "${daily_ppa}" || | 198 | inside "$name" which $addaptrepo >/dev/null || addaptrepo="" |
4139 | 184 | fail "failed add-apt-repository for daily." | 199 | if [ -n "${addaptrepo}" ]; then |
4140 | 200 | inside "$name" ${addaptrepo} --enable-source --yes --no-update \ | ||
4141 | 201 | "${daily_ppa}" || | ||
4142 | 202 | fail "failed add-apt-repository for daily." | ||
4143 | 203 | else | ||
4144 | 204 | # https://launchpad.net/~curtin-dev/+archive/ubuntu/daily | ||
4145 | 205 | local url="http://ppa.launchpad.net/curtin-dev/daily/ubuntu" | ||
4146 | 206 | local lfile="/etc/apt/sources.list.d/curtin-daily-ppa.list" | ||
4147 | 207 | local kfile="/etc/apt/trusted.gpg.d/curtin-daily-ppa.asc" | ||
4148 | 208 | local key="0x1bc30f715a3b861247a81a5e55fe7c8c0165013e" | ||
4149 | 209 | local keyserver="keyserver.ubuntu.com" | ||
4150 | 210 | local keyurl="https://${keyserver}/pks/lookup?op=get&search=${key}" | ||
4151 | 211 | inside "$name" sh -c " | ||
4152 | 212 | echo deb $url $release main > $lfile && | ||
4153 | 213 | wget -q \"$keyurl\" -O $kfile" || | ||
4154 | 214 | fail "failed to add $daily_ppa repository manually" | ||
4155 | 215 | if [ "$getsource" != "none" ]; then | ||
4156 | 216 | inside "$name" sh -c " | ||
4157 | 217 | echo deb-src $url $release main >> $lfile" || | ||
4158 | 218 | fail "failed adding daily ppa deb-src to $lfile" | ||
4159 | 219 | fi | ||
4160 | 220 | fi | ||
4161 | 185 | fi | 221 | fi |
4162 | 186 | 222 | ||
4163 | 187 | line="Acquire::Languages \"none\";" | 223 | line="Acquire::Languages \"none\";" |
4164 | diff --git a/tools/jenkins-runner b/tools/jenkins-runner | |||
4165 | index 253b722..375dc3c 100755 | |||
4166 | --- a/tools/jenkins-runner | |||
4167 | +++ b/tools/jenkins-runner | |||
4168 | @@ -5,6 +5,7 @@ topdir="${CURTIN_VMTEST_TOPDIR:-${WORKSPACE:-$PWD}/output}" | |||
4169 | 5 | pkeep=${CURTIN_VMTEST_KEEP_DATA_PASS:-logs,collect} | 5 | pkeep=${CURTIN_VMTEST_KEEP_DATA_PASS:-logs,collect} |
4170 | 6 | fkeep=${CURTIN_VMTEST_KEEP_DATA_FAIL:-logs,collect} | 6 | fkeep=${CURTIN_VMTEST_KEEP_DATA_FAIL:-logs,collect} |
4171 | 7 | reuse=${CURTIN_VMTEST_REUSE_TOPDIR:-0} | 7 | reuse=${CURTIN_VMTEST_REUSE_TOPDIR:-0} |
4172 | 8 | shuffle=${CURTIN_VMTEST_SHUFFLE_TESTS:-1} | ||
4173 | 8 | declare -i ltimeout=${CURTIN_VMTEST_IMAGE_LOCK_TIMEOUT:-"-1"} | 9 | declare -i ltimeout=${CURTIN_VMTEST_IMAGE_LOCK_TIMEOUT:-"-1"} |
4174 | 9 | export CURTIN_VMTEST_TAR_DISKS=${CURTIN_VMTEST_TAR_DISKS:-0} | 10 | export CURTIN_VMTEST_TAR_DISKS=${CURTIN_VMTEST_TAR_DISKS:-0} |
4175 | 10 | export CURTIN_VMTEST_REUSE_TOPDIR=$reuse | 11 | export CURTIN_VMTEST_REUSE_TOPDIR=$reuse |
4176 | @@ -14,6 +15,7 @@ export CURTIN_VMTEST_KEEP_DATA_FAIL=$fkeep | |||
4177 | 14 | export CURTIN_VMTEST_TOPDIR="$topdir" | 15 | export CURTIN_VMTEST_TOPDIR="$topdir" |
4178 | 15 | export CURTIN_VMTEST_LOG="${CURTIN_VMTEST_LOG:-$topdir/debug.log}" | 16 | export CURTIN_VMTEST_LOG="${CURTIN_VMTEST_LOG:-$topdir/debug.log}" |
4179 | 16 | export CURTIN_VMTEST_PARALLEL=${CURTIN_VMTEST_PARALLEL:-0} | 17 | export CURTIN_VMTEST_PARALLEL=${CURTIN_VMTEST_PARALLEL:-0} |
4180 | 18 | export CURTIN_VMTEST_SHUFFLE_TESTS=$shuffle | ||
4181 | 17 | export IMAGE_DIR=${IMAGE_DIR:-/srv/images} | 19 | export IMAGE_DIR=${IMAGE_DIR:-/srv/images} |
4182 | 18 | 20 | ||
4183 | 19 | # empty TGT_* variables in current env to avoid killing a pid we didn't start. | 21 | # empty TGT_* variables in current env to avoid killing a pid we didn't start. |
4184 | @@ -50,6 +52,15 @@ if [ "$reuse" != "1" ]; then | |||
4185 | 50 | mkdir -p "$topdir" || fail "failed mkdir $topdir" | 52 | mkdir -p "$topdir" || fail "failed mkdir $topdir" |
4186 | 51 | fi | 53 | fi |
4187 | 52 | 54 | ||
4188 | 55 | # Use 'shuf' to randomize test case execution order | ||
4189 | 56 | if [ "$shuffle" == "1" ]; then | ||
4190 | 57 | SHUFFLE="shuf" | ||
4191 | 58 | else | ||
4192 | 59 | # when disabled just repeat the input to output | ||
4193 | 60 | SHUFFLE="tee" | ||
4194 | 61 | fi | ||
4195 | 62 | |||
4196 | 63 | |||
4197 | 53 | start_s=$(date +%s) | 64 | start_s=$(date +%s) |
4198 | 54 | parallel=${CURTIN_VMTEST_PARALLEL} | 65 | parallel=${CURTIN_VMTEST_PARALLEL} |
4199 | 55 | ntfilters=( ) | 66 | ntfilters=( ) |
4200 | @@ -83,9 +94,10 @@ if [ "${#tests[@]}" -ne 0 -a "${#ntfilters[@]}" -ne 0 ]; then | |||
4201 | 83 | error "test arguments provided were: ${#tests[*]}" | 94 | error "test arguments provided were: ${#tests[*]}" |
4202 | 84 | fail | 95 | fail |
4203 | 85 | elif [ "${#tests[@]}" -eq 0 -a "${#ntfilters[@]}" -eq 0 ]; then | 96 | elif [ "${#tests[@]}" -eq 0 -a "${#ntfilters[@]}" -eq 0 ]; then |
4205 | 86 | tests=( tests/vmtests ) | 97 | # run filter without args to enumerate all tests and maybe shuffle |
4206 | 98 | tests=( $(./tools/vmtest-filter | ${SHUFFLE}) ) | ||
4207 | 87 | elif [ "${#ntfilters[@]}" -ne 0 ]; then | 99 | elif [ "${#ntfilters[@]}" -ne 0 ]; then |
4209 | 88 | tests=( $(./tools/vmtest-filter "${ntfilters[@]}") ) | 100 | tests=( $(./tools/vmtest-filter "${ntfilters[@]}" | ${SHUFFLE}) ) |
4210 | 89 | if [ "${#tests[@]}" -eq 0 ]; then | 101 | if [ "${#tests[@]}" -eq 0 ]; then |
4211 | 90 | error "Failed to find any tests with filter(s): \"${ntfilters[*]}\"" | 102 | error "Failed to find any tests with filter(s): \"${ntfilters[*]}\"" |
4212 | 91 | fail "Try testing filters with: ./tools/vmtest-filter ${ntfilters[*]}" | 103 | fail "Try testing filters with: ./tools/vmtest-filter ${ntfilters[*]}" |
4213 | diff --git a/tools/run-pep8 b/tools/run-pep8 | |||
4214 | index c27a96c..227129c 100755 | |||
4215 | --- a/tools/run-pep8 | |||
4216 | +++ b/tools/run-pep8 | |||
4217 | @@ -9,10 +9,10 @@ pycheck_dirs=( | |||
4218 | 9 | "tools/block-discover-to-config" | 9 | "tools/block-discover-to-config" |
4219 | 10 | "tools/curtin-log-print" | 10 | "tools/curtin-log-print" |
4220 | 11 | "tools/noproxy" | 11 | "tools/noproxy" |
4221 | 12 | "tools/remove-vmtest-release" | ||
4222 | 13 | "tools/schema-validate-storage" | 12 | "tools/schema-validate-storage" |
4223 | 14 | "tools/ssh-keys-list" | 13 | "tools/ssh-keys-list" |
4224 | 15 | "tools/vmtest-filter" | 14 | "tools/vmtest-filter" |
4225 | 15 | "tools/vmtest-remove-release" | ||
4226 | 16 | "tools/vmtest-sync-images" | 16 | "tools/vmtest-sync-images" |
4227 | 17 | "tools/webserv" | 17 | "tools/webserv" |
4228 | 18 | "tools/write-curtin" | 18 | "tools/write-curtin" |
4229 | diff --git a/tools/remove-vmtest-release b/tools/vmtest-remove-release | |||
4230 | 19 | similarity index 97% | 19 | similarity index 97% |
4231 | 20 | rename from tools/remove-vmtest-release | 20 | rename from tools/remove-vmtest-release |
4232 | 21 | rename to tools/vmtest-remove-release | 21 | rename to tools/vmtest-remove-release |
4233 | 22 | old mode 100644 | 22 | old mode 100644 |
4234 | 23 | new mode 100755 | 23 | new mode 100755 |
4235 | index 8ab9b2e..d2c5f83 | |||
4236 | --- a/tools/remove-vmtest-release | |||
4237 | +++ b/tools/vmtest-remove-release | |||
4238 | @@ -36,7 +36,7 @@ def clean_file(fname, distro): | |||
4239 | 36 | 36 | ||
4240 | 37 | if __name__ == "__main__": | 37 | if __name__ == "__main__": |
4241 | 38 | parser = argparse.ArgumentParser( | 38 | parser = argparse.ArgumentParser( |
4243 | 39 | prog="remove-vmtest-release", | 39 | prog="vmtest-remove-release", |
4244 | 40 | description="Tool to remove vmtest classes by distro release") | 40 | description="Tool to remove vmtest classes by distro release") |
4245 | 41 | parser.add_argument('--distro-release', '-d', | 41 | parser.add_argument('--distro-release', '-d', |
4246 | 42 | action='store', required=True) | 42 | action='store', required=True) |
LGTM!
(crispyboi) curtin % git fetch upstream //git.launchpad .net/curtin .81144052 master -> upstream/master ubuntu/ devel git/uss- tableflip/ git/uss- tableflip ~/work/ git/curtin/ release/ curtin com:CanonicalLt d/uss-tableflip .575fd654 master -> origin/master lp-attach- file | 2 +- sru-changelog- format | 69 +++++++ +++++++ +++++++ +++++++ +++++++ ------- ------- ------- ------- ------ git/curtin/ release/ curtin git/uss- tableflip/ scripts/ new-upstream- snapshot g81144052- 0ubuntu1) UNRELEASED; urgency=medium duplicates into find/remove functions for reuse grub_device_ ids handle type:mount without path service vmtest- release to vmtest- remove- release
X11 forwarding request failed on channel 0
remote: Enumerating objects: 110, done.
remote: Counting objects: 100% (110/110), done.
remote: Compressing objects: 100% (76/76), done.
remote: Total 76 (delta 62), reused 0 (delta 0)
Unpacking objects: 100% (76/76), 14.69 KiB | 214.00 KiB/s, done.
From git+ssh:
1304d3ea.
(crispyboi) curtin % git bn
ubuntu/devel
(crispyboi) curtin % git reset --hard upstream/
HEAD is now at 34894cc7 releasing curtin version 20.1-0ubuntu1
(crispyboi) curtin % pushd ~/work/
~/work/
(crispyboi) uss-tableflip % git bn
master
(crispyboi) uss-tableflip % git pull
X11 forwarding request failed on channel 0
remote: Enumerating objects: 21, done.
remote: Counting objects: 100% (21/21), done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 21 (delta 14), reused 17 (delta 14), pack-reused 0
Unpacking objects: 100% (21/21), 3.44 KiB | 251.00 KiB/s, done.
From github.
c0641f9c.
Updating c0641f9c..575fd654
Fast-forward
scripts/cla-query | 9 +++------
scripts/log2dch | 10 +++++++++-
scripts/
scripts/
4 files changed, 48 insertions(+), 42 deletions(-)
(crispyboi) uss-tableflip % popd
~/work/
(crispyboi) curtin % ~/work/
updating remote upstream for default commitish upstream/master.
X11 forwarding request failed on channel 0
diff --git a/debian/changelog b/debian/changelog
index e1a75e18..ba612827 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,47 @@
+curtin (20.1-29-
+
+ * New upstream snapshot.
+ - vmtest: Fix multiple issues with vmtest on master
+ - Refactor uefi_remove_
+ - distro: run apt-get clean after dist-upgrade, install, upgrade
+ - curthooks: UEFI remove dupes: don't remove BootCurrent, config option
+ (LP: #1894217)
+ - Pin the dependency on pyrsistent [Paride Legovini]
+ - restore default of grub.update_nvram to True in install_grub
+ [Michael Hudson-Doyle]
+ - block: disk_to_byid_path handle missing /dev/disk/by-id directory
+ (LP: #1876258)
+ - UEFI: Handle missing BootCurrent entry when reordering UEFI entries
+ (LP: #1789650)
+ - dasd: fix off-by-one device_id devno range check [Paride Legovini]
+ - curthooks: uefi_find_
+ (LP: #1892242)
+ - netplan openvswitch yaml changed (LP: #1891608)
+ - tools/curtainer: do not wait for snapd.seeded.
+ - tools/curtainer: enable using ubuntu-minimal images
+ - vmtests: add Groovy [Paride Legovini]
+ - Drop the Eoan vmtests (EOL) [Paride Legovini]
+ - tools: rename remove-
+ - Snooze the tests failing because...