Merge lp:~raharper/curtin/new-bionic-upstream-snapshot-v1 into lp:~curtin-dev/curtin/bionic
- new-bionic-upstream-snapshot-v1
- Merge into bionic
Proposed by
Ryan Harper
Status: | Merged |
---|---|
Merged at revision: | 83 |
Proposed branch: | lp:~raharper/curtin/new-bionic-upstream-snapshot-v1 |
Merge into: | lp:~curtin-dev/curtin/bionic |
Diff against target: |
1202 lines (+350/-270) 36 files modified
curtin/block/__init__.py (+11/-5) curtin/block/clear_holders.py (+33/-4) curtin/commands/block_meta.py (+23/-20) curtin/commands/block_wipe.py (+4/-0) curtin/commands/clear_holders.py (+1/-1) debian/changelog (+17/-0) examples/tests/bcache-wipe-xfs.yaml (+74/-0) examples/tests/uefi_basic.yaml (+23/-0) tests/unittests/test_clear_holders.py (+82/-0) tests/unittests/test_commands_block_meta.py (+11/-15) tests/vmtests/__init__.py (+14/-15) tests/vmtests/releases.py (+0/-11) tests/vmtests/test_basic.py (+0/-48) tests/vmtests/test_bcache_basic.py (+0/-4) tests/vmtests/test_bcache_bug1718699.py (+21/-0) tests/vmtests/test_iscsi.py (+0/-4) tests/vmtests/test_lvm.py (+0/-8) tests/vmtests/test_lvm_iscsi.py (+0/-4) tests/vmtests/test_mdadm_iscsi.py (+0/-4) tests/vmtests/test_network.py (+0/-5) tests/vmtests/test_network_alias.py (+0/-5) tests/vmtests/test_network_bonding.py (+0/-8) tests/vmtests/test_network_enisource.py (+0/-6) tests/vmtests/test_network_ipv6.py (+0/-5) tests/vmtests/test_network_ipv6_enisource.py (+0/-7) tests/vmtests/test_network_ipv6_static.py (+0/-5) tests/vmtests/test_network_ipv6_vlan.py (+0/-16) tests/vmtests/test_network_mtu.py (+1/-6) tests/vmtests/test_network_static.py (+0/-6) tests/vmtests/test_network_static_routes.py (+0/-6) tests/vmtests/test_network_vlan.py (+0/-16) tests/vmtests/test_nvme.py (+0/-5) tests/vmtests/test_raid5_bcache.py (+0/-5) tests/vmtests/test_uefi_basic.py (+1/-15) tools/launch (+10/-10) tools/xkvm (+24/-1) |
To merge this branch: | bzr merge lp:~raharper/curtin/new-bionic-upstream-snapshot-v1 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
curtin developers | Pending | ||
Review via email:
|
Commit message
Description of the change
* New upstream snapshot.
- Drop Precise from vmtest
- clear_holders: bcache log IO/OS exceptions but do not raise
- vmtest: Support newer qemu and multipath.
- block: enable control over exclusive_open use when wiping volumes
- block: handle wiping bcache parts (LP: #1718699)
- vmtests: Defer ArtfulNetworkMtu SkipbyDate to 2018
- bcache: accept sysfs write failure in shutdown handler if path missing
(LP: #1700564)
- vmtest: Rephrase a message about no disks to be less scary
- block_meta: use block.wipe_
(LP: #1722322)
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'curtin/block/__init__.py' |
2 | --- curtin/block/__init__.py 2017-08-03 19:48:07 +0000 |
3 | +++ curtin/block/__init__.py 2017-11-07 18:32:47 +0000 |
4 | @@ -776,17 +776,21 @@ |
5 | |
6 | |
7 | @contextmanager |
8 | -def exclusive_open(path): |
9 | +def exclusive_open(path, exclusive=True): |
10 | """ |
11 | - Obtain an exclusive file-handle to the file/device specified |
12 | + Obtain an exclusive file-handle to the file/device specified unless |
13 | + caller specifics exclusive=False. |
14 | """ |
15 | mode = 'rb+' |
16 | fd = None |
17 | if not os.path.exists(path): |
18 | raise ValueError("No such file at path: %s" % path) |
19 | |
20 | + flags = os.O_RDWR |
21 | + if exclusive: |
22 | + flags += os.O_EXCL |
23 | try: |
24 | - fd = os.open(path, os.O_RDWR | os.O_EXCL) |
25 | + fd = os.open(path, flags) |
26 | try: |
27 | fd_needs_closing = True |
28 | with os.fdopen(fd, mode) as fo: |
29 | @@ -875,7 +879,8 @@ |
30 | return zero_file_at_offsets(path, offsets, buflen=buflen, count=count) |
31 | |
32 | |
33 | -def zero_file_at_offsets(path, offsets, buflen=1024, count=1024, strict=False): |
34 | +def zero_file_at_offsets(path, offsets, buflen=1024, count=1024, strict=False, |
35 | + exclusive=True): |
36 | """ |
37 | write zeros to file at specified offsets |
38 | """ |
39 | @@ -890,7 +895,8 @@ |
40 | tot = buflen * count |
41 | msg_vals = {'path': path, 'tot': buflen * count} |
42 | |
43 | - with exclusive_open(path) as fp: |
44 | + # allow caller to control if we require exclusive open |
45 | + with exclusive_open(path, exclusive=exclusive) as fp: |
46 | # get the size by seeking to end. |
47 | fp.seek(0, 2) |
48 | size = fp.tell() |
49 | |
50 | === modified file 'curtin/block/clear_holders.py' |
51 | --- curtin/block/clear_holders.py 2017-06-12 19:43:55 +0000 |
52 | +++ curtin/block/clear_holders.py 2017-11-07 18:32:47 +0000 |
53 | @@ -93,6 +93,24 @@ |
54 | return path |
55 | |
56 | |
57 | +def maybe_stop_bcache_device(device): |
58 | + """Attempt to stop the provided device_path or raise unexpected errors.""" |
59 | + bcache_stop = os.path.join(device, 'stop') |
60 | + try: |
61 | + util.write_file(bcache_stop, '1', mode=None) |
62 | + except (IOError, OSError) as e: |
63 | + # Note: if we get any exceptions in the above exception classes |
64 | + # it is a result of attempting to write "1" into the sysfs path |
65 | + # The range of errors changes depending on when we race with |
66 | + # the kernel asynchronously removing the sysfs path. Therefore |
67 | + # we log the exception errno we got, but do not re-raise as |
68 | + # the calling process is watching whether the same sysfs path |
69 | + # is being removed; if it fails to go away then we'll have |
70 | + # a log of the exceptions to debug. |
71 | + LOG.debug('Error writing to bcache stop file %s, device removed: %s', |
72 | + bcache_stop, e) |
73 | + |
74 | + |
75 | def shutdown_bcache(device): |
76 | """ |
77 | Shut down bcache for specified bcache device |
78 | @@ -132,8 +150,7 @@ |
79 | os.path.basename(bcache_cache_sysfs)) |
80 | else: |
81 | LOG.info('stopping bcache cacheset at: %s', bcache_cache_sysfs) |
82 | - util.write_file(os.path.join(bcache_cache_sysfs, 'stop'), |
83 | - '1', mode=None) |
84 | + maybe_stop_bcache_device(bcache_cache_sysfs) |
85 | try: |
86 | util.wait_for_removal(bcache_cache_sysfs, retries=removal_retries) |
87 | except OSError: |
88 | @@ -162,8 +179,7 @@ |
89 | return |
90 | else: |
91 | LOG.info('stopping bcache backing device at: %s', bcache_block_sysfs) |
92 | - util.write_file(os.path.join(bcache_block_sysfs, 'stop'), |
93 | - '1', mode=None) |
94 | + maybe_stop_bcache_device(bcache_block_sysfs) |
95 | try: |
96 | # wait for them all to go away |
97 | for dev in [device, bcache_block_sysfs] + slave_paths: |
98 | @@ -244,6 +260,19 @@ |
99 | LOG.info("extended partitions do not need wiping, so skipping: '%s'", |
100 | blockdev) |
101 | else: |
102 | + # some volumes will be claimed by the bcache layer but do not surface |
103 | + # an actual /dev/bcacheN device which owns the parts (backing, cache) |
104 | + # The result is that some volumes cannot be wiped while bcache claims |
105 | + # the device. Resolve this by stopping bcache layer on those volumes |
106 | + # if present. |
107 | + for bcache_path in ['bcache', 'bcache/set']: |
108 | + stop_path = os.path.join(device, bcache_path) |
109 | + if os.path.exists(stop_path): |
110 | + LOG.debug('Attempting to release bcache layer from device: %s', |
111 | + device) |
112 | + maybe_stop_bcache_device(stop_path) |
113 | + continue |
114 | + |
115 | retries = [1, 3, 5, 7] |
116 | LOG.info('wiping superblock on %s', blockdev) |
117 | for attempt, wait in enumerate(retries): |
118 | |
119 | === modified file 'curtin/commands/block_meta.py' |
120 | --- curtin/commands/block_meta.py 2017-06-12 19:43:55 +0000 |
121 | +++ curtin/commands/block_meta.py 2017-11-07 18:32:47 +0000 |
122 | @@ -384,7 +384,11 @@ |
123 | LOG.info("labeling device: '%s' with '%s' partition table", disk, |
124 | ptable) |
125 | if ptable == "gpt": |
126 | - util.subp(["sgdisk", "--clear", disk]) |
127 | + # Wipe both MBR and GPT that may be present on the disk. |
128 | + # N.B.: wipe_volume wipes 1M at front and end of the disk. |
129 | + # This could destroy disk data in filesystems that lived |
130 | + # there. |
131 | + block.wipe_volume(disk, mode='superblock') |
132 | elif ptable in _dos_names: |
133 | util.subp(["parted", disk, "--script", "mklabel", "msdos"]) |
134 | else: |
135 | @@ -544,6 +548,24 @@ |
136 | info.get('id'), device, disk_ptable) |
137 | LOG.debug("partnum: %s offset_sectors: %s length_sectors: %s", |
138 | partnumber, offset_sectors, length_sectors) |
139 | + |
140 | + # Wipe the partition if told to do so, do not wipe dos extended partitions |
141 | + # as this may damage the extended partition table |
142 | + if config.value_as_boolean(info.get('wipe')): |
143 | + LOG.info("Preparing partition location on disk %s", disk) |
144 | + if info.get('flag') == "extended": |
145 | + LOG.warn("extended partitions do not need wiping, so skipping: " |
146 | + "'%s'" % info.get('id')) |
147 | + else: |
148 | + # wipe the start of the new partition first by zeroing 1M at the |
149 | + # length of the previous partition |
150 | + wipe_offset = int(offset_sectors * logical_block_size_bytes) |
151 | + LOG.debug('Wiping 1M on %s at offset %s', disk, wipe_offset) |
152 | + # We don't require exclusive access as we're wiping data at an |
153 | + # offset and the current holder maybe part of the current storage |
154 | + # configuration. |
155 | + block.zero_file_at_offsets(disk, [wipe_offset], exclusive=False) |
156 | + |
157 | if disk_ptable == "msdos": |
158 | if flag in ["extended", "logical", "primary"]: |
159 | partition_type = flag |
160 | @@ -565,25 +587,6 @@ |
161 | else: |
162 | raise ValueError("parent partition has invalid partition table") |
163 | |
164 | - # check if we've triggered hidden metadata like md, lvm or bcache |
165 | - part_kname = get_path_to_storage_volume(info.get('id'), storage_config) |
166 | - holders = clear_holders.get_holders(part_kname) |
167 | - if len(holders) > 0: |
168 | - LOG.debug('Detected block holders on partition %s: %s', part_kname, |
169 | - holders) |
170 | - clear_holders.clear_holders(part_kname) |
171 | - clear_holders.assert_clear(part_kname) |
172 | - |
173 | - # Wipe the partition if told to do so, do not wipe dos extended partitions |
174 | - # as this may damage the extended partition table |
175 | - if config.value_as_boolean(info.get('wipe')): |
176 | - if info.get('flag') == "extended": |
177 | - LOG.warn("extended partitions do not need wiping, so skipping: " |
178 | - "'%s'" % info.get('id')) |
179 | - else: |
180 | - block.wipe_volume( |
181 | - get_path_to_storage_volume(info.get('id'), storage_config), |
182 | - mode=info.get('wipe')) |
183 | # Make the name if needed |
184 | if storage_config.get(device).get('name') and partition_type != 'extended': |
185 | make_dname(info.get('id'), storage_config) |
186 | |
187 | === modified file 'curtin/commands/block_wipe.py' |
188 | --- curtin/commands/block_wipe.py 2016-09-29 18:31:02 +0000 |
189 | +++ curtin/commands/block_wipe.py 2017-11-07 18:32:47 +0000 |
190 | @@ -18,11 +18,15 @@ |
191 | import sys |
192 | import curtin.block as block |
193 | from . import populate_one_subcmd |
194 | +from .. import log |
195 | + |
196 | +LOG = log.LOG |
197 | |
198 | |
199 | def wipe_main(args): |
200 | for blockdev in args.devices: |
201 | try: |
202 | + LOG.debug('Wiping volume %s with mode=%s', blockdev, args.mode) |
203 | block.wipe_volume(blockdev, mode=args.mode) |
204 | except Exception as e: |
205 | sys.stderr.write( |
206 | |
207 | === modified file 'curtin/commands/clear_holders.py' |
208 | --- curtin/commands/clear_holders.py 2016-09-29 18:31:02 +0000 |
209 | +++ curtin/commands/clear_holders.py 2017-11-07 18:32:47 +0000 |
210 | @@ -28,7 +28,7 @@ |
211 | raise ValueError('invalid devices specified') |
212 | block.clear_holders.start_clear_holders_deps() |
213 | block.clear_holders.clear_holders(args.devices, try_preserve=args.preserve) |
214 | - if args.try_preserve: |
215 | + if args.preserve: |
216 | print('ran clear_holders attempting to preserve data. however, ' |
217 | 'hotplug support for some devices may cause holders to restart ') |
218 | block.clear_holders.assert_clear(args.devices) |
219 | |
220 | === modified file 'debian/changelog' |
221 | --- debian/changelog 2017-10-06 02:22:45 +0000 |
222 | +++ debian/changelog 2017-11-07 18:32:47 +0000 |
223 | @@ -1,3 +1,20 @@ |
224 | +curtin (0.1.0~bzr541-0ubuntu1) bionic; urgency=medium |
225 | + |
226 | + * New upstream snapshot. |
227 | + - Drop Precise from vmtest |
228 | + - clear_holders: bcache log IO/OS exceptions but do not raise |
229 | + - vmtest: Support newer qemu and multipath. |
230 | + - block: enable control over exclusive_open use when wiping volumes |
231 | + - block: handle wiping bcache parts (LP: #1718699) |
232 | + - vmtests: Defer ArtfulNetworkMtu SkipbyDate to 2018 |
233 | + - bcache: accept sysfs write failure in shutdown handler if path missing |
234 | + (LP: #1700564) |
235 | + - vmtest: Rephrase a message about no disks to be less scary |
236 | + - block_meta: use block.wipe_volume(mode=superblock) to clear MBR/GPT tables |
237 | + (LP: #1722322) |
238 | + |
239 | + -- Ryan Harper <ryan.harper@canonical.com> Tue, 07 Nov 2017 11:13:00 -0600 |
240 | + |
241 | curtin (0.1.0~bzr532-0ubuntu1) artful; urgency=medium |
242 | |
243 | * New upstream snapshot. |
244 | |
245 | === added file 'examples/tests/bcache-wipe-xfs.yaml' |
246 | --- examples/tests/bcache-wipe-xfs.yaml 1970-01-01 00:00:00 +0000 |
247 | +++ examples/tests/bcache-wipe-xfs.yaml 2017-11-07 18:32:47 +0000 |
248 | @@ -0,0 +1,74 @@ |
249 | +showtrace: true |
250 | + |
251 | +early_commands: |
252 | + # Create a partitioned disk with bcache metadata in one of the partitions. |
253 | + # Then, wipe the partition table. This leaves "buried" bcache data that |
254 | + # would be seen as soon as the disk was partitioned and cause problems |
255 | + # for curtin's use of the disk. |
256 | + # This config recreates issue LP: #1718699 |
257 | + 00_blockmeta: [env, -u, OUTPUT_FSTAB, TARGET_MOUNT_POINT=/tmp/my.bdir/target, |
258 | + WORKING_DIR=/tmp/my.bdir/work.d, curtin, --showtrace, -v, |
259 | + block-meta, --umount, custom] |
260 | + 01_clear_holders: [curtin, clear-holders, --preserve, /dev/vdb] |
261 | + 02_quick_erase: [curtin, block-wipe, --mode, superblock, /dev/vdb] |
262 | + |
263 | +storage: |
264 | + config: |
265 | + - grub_device: true |
266 | + id: vdb |
267 | + name: vdb |
268 | + path: /dev/vdb |
269 | + ptable: msdos |
270 | + type: disk |
271 | + wipe: superblock |
272 | + - id: vdc |
273 | + name: vdc |
274 | + path: /dev/vdc |
275 | + type: disk |
276 | + wipe: superblock |
277 | + - device: vdb |
278 | + id: vdb-part1 |
279 | + name: vdb-part1 |
280 | + number: 1 |
281 | + offset: 4194304B |
282 | + size: 3997171712B |
283 | + type: partition |
284 | + uuid: 1d112703-1ff7-49fb-9655-741016e216bf |
285 | + wipe: superblock |
286 | + - device: vdb |
287 | + id: vdb-part2 |
288 | + name: vdb-part2 |
289 | + number: 2 |
290 | + size: 3997171712B |
291 | + type: partition |
292 | + uuid: ec219a2e-c4a5-4623-b66a-965da2c6c1f1 |
293 | + wipe: superblock |
294 | + - backing_device: vdc |
295 | + cache_device: vdb-part2 |
296 | + cache_mode: writeback |
297 | + id: bcache0 |
298 | + name: bcache0 |
299 | + type: bcache |
300 | + - fstype: ext4 |
301 | + id: vdb-part1_format |
302 | + label: '' |
303 | + type: format |
304 | + uuid: 0687dc8f-c089-4f30-8603-0ddf646a5dd7 |
305 | + volume: vdb-part1 |
306 | + - fstype: xfs |
307 | + id: bcache0_format |
308 | + label: '' |
309 | + type: format |
310 | + uuid: c40a45b2-1f12-454e-a0ec-784eb4ded4e6 |
311 | + volume: bcache0 |
312 | + - device: vdb-part1_format |
313 | + id: vdb-part1_mount |
314 | + options: '' |
315 | + path: / |
316 | + type: mount |
317 | + - device: bcache0_format |
318 | + id: bcache0_mount |
319 | + options: '' |
320 | + path: /var/lib/ceph-bcache/test-disk |
321 | + type: mount |
322 | + version: 1 |
323 | |
324 | === modified file 'examples/tests/uefi_basic.yaml' |
325 | --- examples/tests/uefi_basic.yaml 2016-08-05 20:47:14 +0000 |
326 | +++ examples/tests/uefi_basic.yaml 2017-11-07 18:32:47 +0000 |
327 | @@ -1,4 +1,12 @@ |
328 | showtrace: true |
329 | + |
330 | +early_commands: |
331 | + # Recreate and test LP:1722322 |
332 | + # Make one disk dirty with an MBR and a storage configuration |
333 | + # GPT and don't supply wipe: superblock. This will exercise |
334 | + # curtin use of sgdisk --zap-all instead of --clear (GPT only) |
335 | + blockmeta: ["parted", /dev/vdc, "--script", "mklabel", "msdos"] |
336 | + |
337 | storage: |
338 | config: |
339 | - id: id_disk0 |
340 | @@ -55,4 +63,19 @@ |
341 | id: id_efi_mount |
342 | path: /boot/efi |
343 | type: mount |
344 | + - id: pnum_disk |
345 | + type: disk |
346 | + path: /dev/vdc |
347 | + name: pnum_disk |
348 | + ptable: gpt |
349 | + - id: pnum_disk_p1 |
350 | + type: partition |
351 | + number: 1 |
352 | + size: 1GB |
353 | + device: pnum_disk |
354 | + - id: pnum_disk_p2 |
355 | + type: partition |
356 | + number: 10 |
357 | + size: 1GB |
358 | + device: pnum_disk |
359 | version: 1 |
360 | |
361 | === modified file 'tests/unittests/test_clear_holders.py' |
362 | --- tests/unittests/test_clear_holders.py 2017-08-03 19:48:07 +0000 |
363 | +++ tests/unittests/test_clear_holders.py 2017-11-07 18:32:47 +0000 |
364 | @@ -1,3 +1,4 @@ |
365 | +import errno |
366 | import mock |
367 | import os |
368 | import textwrap |
369 | @@ -329,6 +330,52 @@ |
370 | mock.call(cset, retries=self.remove_retries) |
371 | ]) |
372 | |
373 | + # test bcache shutdown with 'stop' sysfs write failure |
374 | + @mock.patch('curtin.block.clear_holders.udev.udevadm_settle') |
375 | + @mock.patch('curtin.block.clear_holders.get_bcache_sys_path') |
376 | + @mock.patch('curtin.block.clear_holders.util') |
377 | + @mock.patch('curtin.block.clear_holders.os') |
378 | + @mock.patch('curtin.block.clear_holders.LOG') |
379 | + @mock.patch('curtin.block.clear_holders.get_bcache_using_dev') |
380 | + def test_shutdown_bcache_stop_sysfs_write_fails(self, mock_get_bcache, |
381 | + mock_log, mock_os, |
382 | + mock_util, |
383 | + mock_get_bcache_block, |
384 | + mock_udevadm_settle): |
385 | + """Test writes sysfs write failures pass if file not present""" |
386 | + device = "/sys/class/block/null" |
387 | + mock_os.path.exists.side_effect = iter([ |
388 | + True, # backing device exists |
389 | + True, # cset device not present (already removed) |
390 | + False, # backing device is removed with cset |
391 | + False, # bcache/stop sysfs is missing (already removed) |
392 | + ]) |
393 | + cset = '/sys/fs/bcache/fake' |
394 | + mock_get_bcache.return_value = cset |
395 | + mock_get_bcache_block.return_value = device + '/bcache' |
396 | + mock_os.path.join.side_effect = os.path.join |
397 | + |
398 | + # make writes to sysfs fail |
399 | + mock_util.write_file.side_effect = IOError(errno.ENOENT, |
400 | + "File not found") |
401 | + |
402 | + clear_holders.shutdown_bcache(device) |
403 | + |
404 | + self.assertEqual(2, len(mock_log.info.call_args_list)) |
405 | + self.assertEqual(3, len(mock_os.path.exists.call_args_list)) |
406 | + self.assertEqual(1, len(mock_get_bcache.call_args_list)) |
407 | + self.assertEqual(1, len(mock_get_bcache_block.call_args_list)) |
408 | + self.assertEqual(1, len(mock_util.write_file.call_args_list)) |
409 | + self.assertEqual(1, len(mock_util.wait_for_removal.call_args_list)) |
410 | + |
411 | + mock_get_bcache.assert_called_with(device, strict=False) |
412 | + mock_util.write_file.assert_has_calls([ |
413 | + mock.call(cset + '/stop', '1', mode=None), |
414 | + ]) |
415 | + mock_util.wait_for_removal.assert_has_calls([ |
416 | + mock.call(cset, retries=self.remove_retries) |
417 | + ]) |
418 | + |
419 | @mock.patch('curtin.block.clear_holders.LOG') |
420 | @mock.patch('curtin.block.clear_holders.block.sys_block_path') |
421 | @mock.patch('curtin.block.clear_holders.lvm') |
422 | @@ -531,6 +578,41 @@ |
423 | for tree, result in test_trees_and_results: |
424 | self.assertEqual(clear_holders.format_holders_tree(tree), result) |
425 | |
426 | + @mock.patch('curtin.block.clear_holders.util.write_file') |
427 | + def test_maybe_stop_bcache_device_raises_errors(self, m_write_file): |
428 | + """Non-IO/OS exceptions are raised by maybe_stop_bcache_device.""" |
429 | + m_write_file.side_effect = ValueError('Crazy Value Error') |
430 | + with self.assertRaises(ValueError) as cm: |
431 | + clear_holders.maybe_stop_bcache_device('does/not/matter') |
432 | + self.assertEqual('Crazy Value Error', str(cm.exception)) |
433 | + self.assertEqual( |
434 | + mock.call('does/not/matter/stop', '1', mode=None), |
435 | + m_write_file.call_args) |
436 | + |
437 | + @mock.patch('curtin.block.clear_holders.LOG') |
438 | + @mock.patch('curtin.block.clear_holders.util.write_file') |
439 | + def test_maybe_stop_bcache_device_handles_oserror(self, m_write_file, |
440 | + m_log): |
441 | + """When OSError.NOENT is raised, log the condition and move on.""" |
442 | + m_write_file.side_effect = OSError(errno.ENOENT, 'Expected oserror') |
443 | + clear_holders.maybe_stop_bcache_device('does/not/matter') |
444 | + self.assertEqual( |
445 | + 'Error writing to bcache stop file %s, device removed: %s', |
446 | + m_log.debug.call_args[0][0]) |
447 | + self.assertEqual('does/not/matter/stop', m_log.debug.call_args[0][1]) |
448 | + |
449 | + @mock.patch('curtin.block.clear_holders.LOG') |
450 | + @mock.patch('curtin.block.clear_holders.util.write_file') |
451 | + def test_maybe_stop_bcache_device_handles_ioerror(self, m_write_file, |
452 | + m_log): |
453 | + """When IOError.NOENT is raised, log the condition and move on.""" |
454 | + m_write_file.side_effect = IOError(errno.ENOENT, 'Expected ioerror') |
455 | + clear_holders.maybe_stop_bcache_device('does/not/matter') |
456 | + self.assertEqual( |
457 | + 'Error writing to bcache stop file %s, device removed: %s', |
458 | + m_log.debug.call_args[0][0]) |
459 | + self.assertEqual('does/not/matter/stop', m_log.debug.call_args[0][1]) |
460 | + |
461 | def test_get_holder_types(self): |
462 | """test clear_holders.get_holder_types""" |
463 | test_trees_and_results = [ |
464 | |
465 | === modified file 'tests/unittests/test_commands_block_meta.py' |
466 | --- tests/unittests/test_commands_block_meta.py 2017-08-03 19:48:07 +0000 |
467 | +++ tests/unittests/test_commands_block_meta.py 2017-11-07 18:32:47 +0000 |
468 | @@ -130,6 +130,8 @@ |
469 | 'mock_clear_holders') |
470 | self.add_patch('curtin.block.clear_holders.assert_clear', |
471 | 'mock_assert_clear') |
472 | + self.add_patch('curtin.block.zero_file_at_offsets', |
473 | + 'mock_block_zero_file') |
474 | |
475 | self.target = "my_target" |
476 | self.config = { |
477 | @@ -177,32 +179,26 @@ |
478 | self.mock_clear_holders.assert_called_with(disk) |
479 | self.mock_assert_clear.assert_called_with(disk) |
480 | |
481 | - def test_partition_handler_calls_clear_holder(self): |
482 | + def test_partition_handler_wipes_at_partition_offset(self): |
483 | + """ Test wiping partition at offset prior to creating partition""" |
484 | disk_info = self.storage_config.get('sda') |
485 | part_info = self.storage_config.get('sda-part1') |
486 | disk_kname = disk_info.get('path') |
487 | part_kname = disk_kname + '1' |
488 | self.mock_getpath.side_effect = iter([ |
489 | - disk_info.get('id'), |
490 | - part_kname, |
491 | - part_kname, |
492 | + disk_kname, |
493 | part_kname, |
494 | ]) |
495 | - |
496 | self.mock_block_get_part_table_type.return_value = 'dos' |
497 | kname = 'xxx' |
498 | self.mock_block_path_to_kname.return_value = kname |
499 | self.mock_block_sys_block_path.return_value = '/sys/class/block/xxx' |
500 | - self.mock_subp.side_effect = iter([ |
501 | - ("", 0), # parted mkpart |
502 | - ("", 0), # ?? |
503 | - ]) |
504 | - holders = ['md1'] |
505 | - self.mock_get_holders.return_value = holders |
506 | |
507 | block_meta.partition_handler(part_info, self.storage_config) |
508 | |
509 | - print("clear_holders: %s" % self.mock_clear_holders.call_args_list) |
510 | - print("assert_clear: %s" % self.mock_assert_clear.call_args_list) |
511 | - self.mock_clear_holders.assert_called_with(part_kname) |
512 | - self.mock_assert_clear.assert_called_with(part_kname) |
513 | + part_offset = 2048 * 512 |
514 | + self.mock_block_zero_file.assert_called_with(disk_kname, [part_offset], |
515 | + exclusive=False) |
516 | + self.mock_subp.assert_called_with(['parted', disk_kname, '--script', |
517 | + 'mkpart', 'primary', '2048s', |
518 | + '1001471s'], capture=True) |
519 | |
520 | === modified file 'tests/vmtests/__init__.py' |
521 | --- tests/vmtests/__init__.py 2017-10-06 02:20:08 +0000 |
522 | +++ tests/vmtests/__init__.py 2017-11-07 18:32:47 +0000 |
523 | @@ -699,9 +699,6 @@ |
524 | logger.info('Detected centos, adding default config %s', |
525 | centos_default) |
526 | |
527 | - if cls.multipath: |
528 | - disks = disks * cls.multipath_num_paths |
529 | - |
530 | # set reporting logger |
531 | cls.reporting_log = os.path.join(cls.td.logs, 'webhooks-events.json') |
532 | reporting_logger = CaptureReporting(cls.reporting_log) |
533 | @@ -727,7 +724,7 @@ |
534 | })) |
535 | configs.append(reporting_config) |
536 | |
537 | - cmd.extend(uefi_flags + netdevs + disks + |
538 | + cmd.extend(uefi_flags + netdevs + cls.mpath_diskargs(disks) + |
539 | [ftypes['vmtest.root-image'], "--kernel=%s" % |
540 | ftypes['boot-kernel'], "--initrd=%s" % |
541 | ftypes['boot-initrd'], "--", "curtin", "-vv", "install"] + |
542 | @@ -825,11 +822,6 @@ |
543 | # unlike NVMe disks, we do not want to configure the iSCSI disks |
544 | # via KVM, which would use qemu's iSCSI target layer. |
545 | |
546 | - if cls.multipath: |
547 | - target_disks = target_disks * cls.multipath_num_paths |
548 | - extra_disks = extra_disks * cls.multipath_num_paths |
549 | - nvme_disks = nvme_disks * cls.multipath_num_paths |
550 | - |
551 | # output disk is always virtio-blk, with serial of output_disk.img |
552 | output_disk = '--disk={},driver={},format={},{},{}'.format( |
553 | cls.td.output_disk, 'virtio-blk', |
554 | @@ -840,11 +832,9 @@ |
555 | # create xkvm cmd |
556 | cmd = (["tools/xkvm", "-v", dowait] + |
557 | uefi_flags + netdevs + |
558 | - target_disks + extra_disks + nvme_disks + |
559 | - ["--", "-drive", |
560 | - "file=%s,if=virtio,media=cdrom" % cls.td.seed_disk, |
561 | - "-smp", cls.get_config_smp(), |
562 | - "-m", "1024"]) |
563 | + cls.mpath_diskargs(target_disks + extra_disks + nvme_disks) + |
564 | + ["--disk=file=%s,if=virtio,media=cdrom" % cls.td.seed_disk] + |
565 | + ["--", "-smp", cls.get_config_smp(), "-m", "1024"]) |
566 | |
567 | if not cls.interactive: |
568 | if cls.arch == 's390x': |
569 | @@ -1007,6 +997,15 @@ |
570 | # prepending ./ makes '/root/file' or 'root/file' work as expected. |
571 | return os.path.normpath(os.path.join(cls.td.collect, "./" + path)) |
572 | |
573 | + @classmethod |
574 | + def mpath_diskargs(cls, disks): |
575 | + """make multipath versions of --disk args in disks.""" |
576 | + if not cls.multipath: |
577 | + return disks |
578 | + opt = ",file.locking=off" |
579 | + return ([d if d == "--disk" else d + opt for d in disks] * |
580 | + cls.multipath_num_paths) |
581 | + |
582 | # Misc functions that are useful for many tests |
583 | def output_files_exist(self, files): |
584 | logger.debug('checking files exist: %s', files) |
585 | @@ -1459,7 +1458,7 @@ |
586 | logger.info('Taring %s disks sparsely to %s', len(disks), outfile) |
587 | util.subp(cmd, capture=True) |
588 | else: |
589 | - logger.error('Failed to find "disks" dir under tmpdir: %s', tmpdir) |
590 | + logger.debug('No "disks" dir found in tmpdir: %s', tmpdir) |
591 | |
592 | |
593 | def boot_log_wrap(name, func, cmd, console_log, timeout, purpose): |
594 | |
595 | === modified file 'tests/vmtests/releases.py' |
596 | --- tests/vmtests/releases.py 2017-08-03 19:48:07 +0000 |
597 | +++ tests/vmtests/releases.py 2017-11-07 18:32:47 +0000 |
598 | @@ -39,15 +39,6 @@ |
599 | target_release = "centos66" |
600 | |
601 | |
602 | -class _PreciseBase(_UbuntuBase): |
603 | - release = "precise" |
604 | - |
605 | - |
606 | -class _PreciseHWET(_UbuntuBase): |
607 | - release = "precise" |
608 | - krel = "trusty" |
609 | - |
610 | - |
611 | class _TrustyBase(_UbuntuBase): |
612 | release = "trusty" |
613 | |
614 | @@ -90,8 +81,6 @@ |
615 | |
616 | |
617 | class _Releases(object): |
618 | - precise = _PreciseBase |
619 | - precise_hwe_t = _PreciseHWET |
620 | trusty = _TrustyBase |
621 | trusty_hwe_u = _TrustyHWEU |
622 | trusty_hwe_v = _TrustyHWEV |
623 | |
624 | === modified file 'tests/vmtests/test_basic.py' |
625 | --- tests/vmtests/test_basic.py 2017-08-03 19:48:07 +0000 |
626 | +++ tests/vmtests/test_basic.py 2017-11-07 18:32:47 +0000 |
627 | @@ -137,49 +137,6 @@ |
628 | self.assertEqual(source_version, installed_version) |
629 | |
630 | |
631 | -class PreciseTestBasic(relbase.precise, TestBasicAbs): |
632 | - __test__ = True |
633 | - |
634 | - collect_scripts = [textwrap.dedent(""" |
635 | - cd OUTPUT_COLLECT_D |
636 | - blkid -o export /dev/vda > blkid_output_vda |
637 | - blkid -o export /dev/vda1 > blkid_output_vda1 |
638 | - blkid -o export /dev/vda2 > blkid_output_vda2 |
639 | - f="btrfs_uuid_vdd" |
640 | - btrfs-show /dev/vdd | awk '/uuid/ {print $4}' > $f |
641 | - cat /proc/partitions > proc_partitions |
642 | - ls -al /dev/disk/by-uuid/ > ls_uuid |
643 | - cat /etc/fstab > fstab |
644 | - mkdir -p /dev/disk/by-dname |
645 | - ls /dev/disk/by-dname/ > ls_dname |
646 | - find /etc/network/interfaces.d > find_interfacesd |
647 | - |
648 | - v="" |
649 | - out=$(apt-config shell v Acquire::HTTP::Proxy) |
650 | - eval "$out" |
651 | - echo "$v" > apt-proxy |
652 | - """)] |
653 | - |
654 | - def test_whole_disk_format(self): |
655 | - # confirm the whole disk format is the expected device |
656 | - btrfs_uuid = self.load_collect_file("btrfs_uuid_vdd").strip() |
657 | - |
658 | - self.assertTrue(btrfs_uuid is not None) |
659 | - self.assertEqual(len(btrfs_uuid), 36) |
660 | - |
661 | - # extract uuid from ls_uuid by kname |
662 | - kname_uuid = self._kname_to_uuid('vdd') |
663 | - |
664 | - # compare them |
665 | - self.assertEqual(kname_uuid, btrfs_uuid) |
666 | - |
667 | - def test_ptable(self): |
668 | - print("test_ptable does not work for Precise") |
669 | - |
670 | - def test_dname(self): |
671 | - print("test_dname does not work for Precise") |
672 | - |
673 | - |
674 | class TrustyTestBasic(relbase.trusty, TestBasicAbs): |
675 | __test__ = True |
676 | |
677 | @@ -193,11 +150,6 @@ |
678 | print("test_ptable does not work for Trusty") |
679 | |
680 | |
681 | -class PreciseHWETTestBasic(relbase.precise_hwe_t, PreciseTestBasic): |
682 | - # FIXME: off due to test_whole_disk_format failing |
683 | - __test__ = False |
684 | - |
685 | - |
686 | class TrustyHWEXTestBasic(relbase.trusty_hwe_x, TrustyTestBasic): |
687 | __test__ = True |
688 | |
689 | |
690 | === modified file 'tests/vmtests/test_bcache_basic.py' |
691 | --- tests/vmtests/test_bcache_basic.py 2017-08-03 19:48:07 +0000 |
692 | +++ tests/vmtests/test_bcache_basic.py 2017-11-07 18:32:47 +0000 |
693 | @@ -43,10 +43,6 @@ |
694 | self.check_file_regex("cmdline", r"root=UUID=") |
695 | |
696 | |
697 | -class PreciseHWETBcacheBasic(relbase.precise_hwe_t, TestBcacheBasic): |
698 | - __test__ = True |
699 | - |
700 | - |
701 | class TrustyBcacheBasic(relbase.trusty, TestBcacheBasic): |
702 | __test__ = False # covered by test_raid5_bcache |
703 | |
704 | |
705 | === added file 'tests/vmtests/test_bcache_bug1718699.py' |
706 | --- tests/vmtests/test_bcache_bug1718699.py 1970-01-01 00:00:00 +0000 |
707 | +++ tests/vmtests/test_bcache_bug1718699.py 2017-11-07 18:32:47 +0000 |
708 | @@ -0,0 +1,21 @@ |
709 | +from .releases import base_vm_classes as relbase |
710 | +from .test_bcache_basic import TestBcacheBasic |
711 | + |
712 | + |
713 | +class TestBcacheBug1718699(TestBcacheBasic): |
714 | + conf_file = "examples/tests/bcache-wipe-xfs.yaml" |
715 | + dirty_disks = False |
716 | + nr_cpus = 2 |
717 | + extra_disks = ['10G'] |
718 | + |
719 | + |
720 | +class XenialTestBcacheBug1718699(relbase.xenial, TestBcacheBug1718699): |
721 | + __test__ = True |
722 | + |
723 | + |
724 | +class ZestyTestBcacheBug1718699(relbase.zesty, TestBcacheBug1718699): |
725 | + __test__ = True |
726 | + |
727 | + |
728 | +class ArtfulTestBcacheBug1718699(relbase.artful, TestBcacheBug1718699): |
729 | + __test__ = True |
730 | |
731 | === modified file 'tests/vmtests/test_iscsi.py' |
732 | --- tests/vmtests/test_iscsi.py 2017-08-03 19:48:07 +0000 |
733 | +++ tests/vmtests/test_iscsi.py 2017-11-07 18:32:47 +0000 |
734 | @@ -47,10 +47,6 @@ |
735 | (testfile, expected_content, content)) |
736 | |
737 | |
738 | -class PreciseTestIscsiBasic(relbase.precise, TestBasicIscsiAbs): |
739 | - __test__ = True |
740 | - |
741 | - |
742 | class TrustyTestIscsiBasic(relbase.trusty, TestBasicIscsiAbs): |
743 | __test__ = True |
744 | |
745 | |
746 | === modified file 'tests/vmtests/test_lvm.py' |
747 | --- tests/vmtests/test_lvm.py 2017-08-03 19:48:07 +0000 |
748 | +++ tests/vmtests/test_lvm.py 2017-11-07 18:32:47 +0000 |
749 | @@ -48,14 +48,6 @@ |
750 | raise SkipTest("test_dname does not work for %s" % self.release) |
751 | |
752 | |
753 | -class PreciseTestLvm(relbase.precise, TestLvmAbs): |
754 | - __test__ = True |
755 | - |
756 | - |
757 | -class PreciseHWETTestLvm(relbase.precise_hwe_t, PreciseTestLvm): |
758 | - __test__ = True |
759 | - |
760 | - |
761 | class TrustyTestLvm(relbase.trusty, TestLvmAbs): |
762 | __test__ = True |
763 | |
764 | |
765 | === modified file 'tests/vmtests/test_lvm_iscsi.py' |
766 | --- tests/vmtests/test_lvm_iscsi.py 2017-10-06 02:20:08 +0000 |
767 | +++ tests/vmtests/test_lvm_iscsi.py 2017-11-07 18:32:47 +0000 |
768 | @@ -47,10 +47,6 @@ |
769 | self.check_file_strippedline("pvs", "vg2=/dev/sdb6") |
770 | |
771 | |
772 | -class PreciseTestIscsiLvm(relbase.precise, TestLvmIscsiAbs): |
773 | - __test__ = True |
774 | - |
775 | - |
776 | class TrustyTestIscsiLvm(relbase.trusty, TestLvmIscsiAbs): |
777 | __test__ = True |
778 | |
779 | |
780 | === modified file 'tests/vmtests/test_mdadm_iscsi.py' |
781 | --- tests/vmtests/test_mdadm_iscsi.py 2017-10-06 02:20:08 +0000 |
782 | +++ tests/vmtests/test_mdadm_iscsi.py 2017-11-07 18:32:47 +0000 |
783 | @@ -22,10 +22,6 @@ |
784 | """)] |
785 | |
786 | |
787 | -class PreciseTestIscsiMdadm(relbase.precise, TestMdadmIscsiAbs): |
788 | - __test__ = True |
789 | - |
790 | - |
791 | class TrustyTestIscsiMdadm(relbase.trusty, TestMdadmIscsiAbs): |
792 | __test__ = True |
793 | |
794 | |
795 | === modified file 'tests/vmtests/test_network.py' |
796 | --- tests/vmtests/test_network.py 2017-10-06 02:20:08 +0000 |
797 | +++ tests/vmtests/test_network.py 2017-11-07 18:32:47 +0000 |
798 | @@ -449,11 +449,6 @@ |
799 | pass |
800 | |
801 | |
802 | -class PreciseHWETTestNetworkBasic(relbase.precise_hwe_t, TestNetworkBasicAbs): |
803 | - # FIXME: off due to hang at test: Starting execute cloud user/final scripts |
804 | - __test__ = False |
805 | - |
806 | - |
807 | class TrustyTestNetworkBasic(relbase.trusty, TestNetworkBasicAbs): |
808 | __test__ = True |
809 | |
810 | |
811 | === modified file 'tests/vmtests/test_network_alias.py' |
812 | --- tests/vmtests/test_network_alias.py 2017-08-03 19:48:07 +0000 |
813 | +++ tests/vmtests/test_network_alias.py 2017-11-07 18:32:47 +0000 |
814 | @@ -41,11 +41,6 @@ |
815 | __test__ = True |
816 | |
817 | |
818 | -class PreciseHWETTestNetworkAlias(relbase.precise_hwe_t, TestNetworkAliasAbs): |
819 | - # FIXME: off due to hang at test: Starting execute cloud user/final scripts |
820 | - __test__ = True |
821 | - |
822 | - |
823 | class TrustyTestNetworkAlias(relbase.trusty, TestNetworkAliasAbs): |
824 | __test__ = True |
825 | |
826 | |
827 | === modified file 'tests/vmtests/test_network_bonding.py' |
828 | --- tests/vmtests/test_network_bonding.py 2017-10-06 02:20:08 +0000 |
829 | +++ tests/vmtests/test_network_bonding.py 2017-11-07 18:32:47 +0000 |
830 | @@ -38,14 +38,6 @@ |
831 | pass |
832 | |
833 | |
834 | -class PreciseHWETTestBonding(relbase.precise_hwe_t, TestNetworkBondingAbs): |
835 | - __test__ = True |
836 | - |
837 | - def test_ifenslave_installed(self): |
838 | - self.assertIn("ifenslave-2.6", self.debian_packages, |
839 | - "ifenslave deb not installed") |
840 | - |
841 | - |
842 | class TrustyTestBonding(relbase.trusty, TestNetworkBondingAbs): |
843 | __test__ = False |
844 | |
845 | |
846 | === modified file 'tests/vmtests/test_network_enisource.py' |
847 | --- tests/vmtests/test_network_enisource.py 2017-10-06 02:20:08 +0000 |
848 | +++ tests/vmtests/test_network_enisource.py 2017-11-07 18:32:47 +0000 |
849 | @@ -79,12 +79,6 @@ |
850 | self.assertEqual(_nocidr(expected_address), _nocidr(actual_address)) |
851 | |
852 | |
853 | -class PreciseTestNetworkENISource(relbase.precise, TestNetworkENISource): |
854 | - __test__ = False |
855 | - # not working, still debugging though; possible older ifupdown doesn't |
856 | - # like the multiple iface method. |
857 | - |
858 | - |
859 | class TrustyTestNetworkENISource(relbase.trusty, TestNetworkENISource): |
860 | __test__ = True |
861 | |
862 | |
863 | === modified file 'tests/vmtests/test_network_ipv6.py' |
864 | --- tests/vmtests/test_network_ipv6.py 2017-10-06 02:20:08 +0000 |
865 | +++ tests/vmtests/test_network_ipv6.py 2017-11-07 18:32:47 +0000 |
866 | @@ -40,11 +40,6 @@ |
867 | pass |
868 | |
869 | |
870 | -class PreciseHWETTestNetwork(relbase.precise_hwe_t, TestNetworkIPV6Abs): |
871 | - # FIXME: off due to hang at test: Starting execute cloud user/final scripts |
872 | - __test__ = False |
873 | - |
874 | - |
875 | class TrustyTestNetworkIPV6(relbase.trusty, TestNetworkIPV6Abs): |
876 | __test__ = True |
877 | |
878 | |
879 | === modified file 'tests/vmtests/test_network_ipv6_enisource.py' |
880 | --- tests/vmtests/test_network_ipv6_enisource.py 2017-10-06 02:20:08 +0000 |
881 | +++ tests/vmtests/test_network_ipv6_enisource.py 2017-11-07 18:32:47 +0000 |
882 | @@ -12,13 +12,6 @@ |
883 | pass |
884 | |
885 | |
886 | -class PreciseTestNetworkIPV6ENISource(relbase.precise, |
887 | - TestNetworkIPV6ENISource): |
888 | - __test__ = False |
889 | - # not working, still debugging though; possible older ifupdown doesn't |
890 | - # like the multiple iface method. |
891 | - |
892 | - |
893 | class TrustyTestNetworkIPV6ENISource(relbase.trusty, TestNetworkIPV6ENISource): |
894 | __test__ = True |
895 | |
896 | |
897 | === modified file 'tests/vmtests/test_network_ipv6_static.py' |
898 | --- tests/vmtests/test_network_ipv6_static.py 2017-08-03 19:48:07 +0000 |
899 | +++ tests/vmtests/test_network_ipv6_static.py 2017-11-07 18:32:47 +0000 |
900 | @@ -13,11 +13,6 @@ |
901 | conf_file = "examples/tests/basic_network_static_ipv6.yaml" |
902 | |
903 | |
904 | -class PreciseHWETTestNetworkIPV6Static(relbase.precise_hwe_t, |
905 | - TestNetworkIPV6StaticAbs): |
906 | - __test__ = True |
907 | - |
908 | - |
909 | class TrustyTestNetworkIPV6Static(relbase.trusty, TestNetworkIPV6StaticAbs): |
910 | __test__ = True |
911 | |
912 | |
913 | === modified file 'tests/vmtests/test_network_ipv6_vlan.py' |
914 | --- tests/vmtests/test_network_ipv6_vlan.py 2017-10-06 02:20:08 +0000 |
915 | +++ tests/vmtests/test_network_ipv6_vlan.py 2017-11-07 18:32:47 +0000 |
916 | @@ -12,22 +12,6 @@ |
917 | conf_file = "examples/tests/vlan_network_ipv6.yaml" |
918 | |
919 | |
920 | -class PreciseTestNetworkIPV6Vlan(relbase.precise, TestNetworkIPV6VlanAbs): |
921 | - __test__ = True |
922 | - |
923 | - # precise ip -d link show output is different (of course) |
924 | - def test_vlan_enabled(self): |
925 | - |
926 | - # we must have at least one |
927 | - self.assertGreaterEqual(len(self.get_vlans()), 1) |
928 | - |
929 | - # did they get configured? |
930 | - for vlan in self.get_vlans(): |
931 | - link_file = "ip_link_show_" + vlan['name'] |
932 | - vlan_msg = "vlan id " + str(vlan['vlan_id']) |
933 | - self.check_file_regex(link_file, vlan_msg) |
934 | - |
935 | - |
936 | class TrustyTestNetworkIPV6Vlan(relbase.trusty, TestNetworkIPV6VlanAbs): |
937 | __test__ = True |
938 | |
939 | |
940 | === modified file 'tests/vmtests/test_network_mtu.py' |
941 | --- tests/vmtests/test_network_mtu.py 2017-10-06 02:20:08 +0000 |
942 | +++ tests/vmtests/test_network_mtu.py 2017-11-07 18:32:47 +0000 |
943 | @@ -155,11 +155,6 @@ |
944 | pass |
945 | |
946 | |
947 | -class PreciseHWETTestNetworkMtu(relbase.precise_hwe_t, TestNetworkMtuAbs): |
948 | - # FIXME: Precise mtu / ipv6 is buggy |
949 | - __test__ = False |
950 | - |
951 | - |
952 | class TrustyTestNetworkMtu(relbase.trusty, TestNetworkMtuAbs): |
953 | __test__ = True |
954 | |
955 | @@ -203,7 +198,7 @@ |
956 | @classmethod |
957 | def setUpClass(cls): |
958 | cls.skip_by_date(cls.__name__, cls.release, "1671951", |
959 | - fixby=(2017, 10, 20), removeby=(2018, 1, 23)) |
960 | + fixby=(2018, 1, 20), removeby=(2018, 2, 23)) |
961 | super().setUpClass() |
962 | |
963 | |
964 | |
965 | === modified file 'tests/vmtests/test_network_static.py' |
966 | --- tests/vmtests/test_network_static.py 2017-08-03 19:48:07 +0000 |
967 | +++ tests/vmtests/test_network_static.py 2017-11-07 18:32:47 +0000 |
968 | @@ -28,12 +28,6 @@ |
969 | pass |
970 | |
971 | |
972 | -class PreciseHWETTestNetworkStatic(relbase.precise_hwe_t, |
973 | - TestNetworkStaticAbs): |
974 | - # FIXME: off due to hang at test: Starting execute cloud user/final scripts |
975 | - __test__ = False |
976 | - |
977 | - |
978 | class TrustyTestNetworkStatic(relbase.trusty, TestNetworkStaticAbs): |
979 | __test__ = True |
980 | |
981 | |
982 | === modified file 'tests/vmtests/test_network_static_routes.py' |
983 | --- tests/vmtests/test_network_static_routes.py 2017-08-03 19:48:07 +0000 |
984 | +++ tests/vmtests/test_network_static_routes.py 2017-11-07 18:32:47 +0000 |
985 | @@ -16,12 +16,6 @@ |
986 | conf_file = "examples/tests/network_static_routes.yaml" |
987 | |
988 | |
989 | -class PreciseHWETTestNetworkStaticRoutes(relbase.precise_hwe_t, |
990 | - TestNetworkStaticRoutesAbs): |
991 | - # FIXME: off due to hang at test: Starting execute cloud user/final scripts |
992 | - __test__ = False |
993 | - |
994 | - |
995 | class TrustyTestNetworkStaticRoutes(relbase.trusty, |
996 | TestNetworkStaticRoutesAbs): |
997 | __test__ = True |
998 | |
999 | === modified file 'tests/vmtests/test_network_vlan.py' |
1000 | --- tests/vmtests/test_network_vlan.py 2017-10-06 02:20:08 +0000 |
1001 | +++ tests/vmtests/test_network_vlan.py 2017-11-07 18:32:47 +0000 |
1002 | @@ -68,22 +68,6 @@ |
1003 | pass |
1004 | |
1005 | |
1006 | -class PreciseTestNetworkVlan(relbase.precise, TestNetworkVlanAbs): |
1007 | - __test__ = True |
1008 | - |
1009 | - # precise ip -d link show output is different (of course) |
1010 | - def test_vlan_enabled(self): |
1011 | - |
1012 | - # we must have at least one |
1013 | - self.assertGreaterEqual(len(self.get_vlans()), 1) |
1014 | - |
1015 | - # did they get configured? |
1016 | - for vlan in self.get_vlans(): |
1017 | - link_file = "ip_link_show_" + vlan['name'] |
1018 | - vlan_msg = "vlan id " + str(vlan['vlan_id']) |
1019 | - self.check_file_regex(link_file, vlan_msg) |
1020 | - |
1021 | - |
1022 | class TrustyTestNetworkVlan(relbase.trusty, TestNetworkVlanAbs): |
1023 | __test__ = True |
1024 | |
1025 | |
1026 | === modified file 'tests/vmtests/test_nvme.py' |
1027 | --- tests/vmtests/test_nvme.py 2017-08-03 19:48:07 +0000 |
1028 | +++ tests/vmtests/test_nvme.py 2017-11-07 18:32:47 +0000 |
1029 | @@ -53,11 +53,6 @@ |
1030 | self.check_file_strippedline("ls_dev_nvme", "/dev/nvme1") |
1031 | |
1032 | |
1033 | -class PreciseTestNvme(relbase.precise, TestNvmeAbs): |
1034 | - __test__ = False |
1035 | - # Precise kernel doesn't have NVME support, with TrustyHWE it would |
1036 | - |
1037 | - |
1038 | class TrustyTestNvme(relbase.trusty, TestNvmeAbs): |
1039 | __test__ = True |
1040 | |
1041 | |
1042 | === modified file 'tests/vmtests/test_raid5_bcache.py' |
1043 | --- tests/vmtests/test_raid5_bcache.py 2017-08-03 19:48:07 +0000 |
1044 | +++ tests/vmtests/test_raid5_bcache.py 2017-11-07 18:32:47 +0000 |
1045 | @@ -65,11 +65,6 @@ |
1046 | self.check_file_regex("bcache_cache_mode", r"\[writeback\]") |
1047 | |
1048 | |
1049 | -class PreciseHWETTestRaid5Bcache(relbase.precise_hwe_t, TestMdadmBcacheAbs): |
1050 | - # FIXME: off due to failing install: RUN_ARRAY failed: Invalid argument |
1051 | - __test__ = False |
1052 | - |
1053 | - |
1054 | class TrustyTestRaid5Bcache(relbase.trusty, TestMdadmBcacheAbs): |
1055 | __test__ = True |
1056 | # FIXME(LP: #1523037): dname does not work on trusty, so we cannot expect |
1057 | |
1058 | === modified file 'tests/vmtests/test_uefi_basic.py' |
1059 | --- tests/vmtests/test_uefi_basic.py 2017-08-03 19:48:07 +0000 |
1060 | +++ tests/vmtests/test_uefi_basic.py 2017-11-07 18:32:47 +0000 |
1061 | @@ -9,7 +9,7 @@ |
1062 | interactive = False |
1063 | arch_skip = ["s390x"] |
1064 | conf_file = "examples/tests/uefi_basic.yaml" |
1065 | - extra_disks = [] |
1066 | + extra_disks = ['4G'] |
1067 | uefi = True |
1068 | disk_to_check = [('main_disk', 1), ('main_disk', 2), ('main_disk', 3)] |
1069 | collect_scripts = [textwrap.dedent(""" |
1070 | @@ -76,16 +76,6 @@ |
1071 | self.assertEqual(self.disk_block_size, size) |
1072 | |
1073 | |
1074 | -class PreciseUefiTestBasic(relbase.precise, TestBasicAbs): |
1075 | - __test__ = True |
1076 | - |
1077 | - def test_ptable(self): |
1078 | - print("test_ptable does not work for Precise") |
1079 | - |
1080 | - def test_dname(self): |
1081 | - print("test_dname does not work for Precise") |
1082 | - |
1083 | - |
1084 | class TrustyUefiTestBasic(relbase.trusty, TestBasicAbs): |
1085 | __test__ = True |
1086 | |
1087 | @@ -115,10 +105,6 @@ |
1088 | __test__ = True |
1089 | |
1090 | |
1091 | -class PreciseUefiTestBasic4k(PreciseUefiTestBasic): |
1092 | - disk_block_size = 4096 |
1093 | - |
1094 | - |
1095 | class TrustyUefiTestBasic4k(TrustyUefiTestBasic): |
1096 | disk_block_size = 4096 |
1097 | |
1098 | |
1099 | === modified file 'tools/launch' |
1100 | --- tools/launch 2017-08-03 19:48:07 +0000 |
1101 | +++ tools/launch 2017-11-07 18:32:47 +0000 |
1102 | @@ -583,11 +583,10 @@ |
1103 | bs_args="${bs_args},physical_block_size=$phybs" |
1104 | bs_args="${bs_args},min_io_size=$logbs" |
1105 | |
1106 | - disk_args=( "${disk_args[@]}" "-drive" |
1107 | - "file=${src},if=none,cache=unsafe,format=$fmt,id=drv${id},index=$id" ) |
1108 | - |
1109 | - disk_args=( "${disk_args[@]}" "-device" |
1110 | - "${driver},drive=drv${id},${bs_args}${devopts}" ) |
1111 | + t="file=${src},if=none,cache=unsafe,format=$fmt," |
1112 | + t="${t}id=drv${id},index=$id," |
1113 | + t="${t}driver=${driver},${bs_args}${devopts}" |
1114 | + disk_args[${#disk_args[@]}]="--disk=$t" |
1115 | |
1116 | done |
1117 | |
1118 | @@ -754,7 +753,7 @@ |
1119 | seed="${TEMP_D}/seed.img" |
1120 | cloud-localds "$seed" "$udata" "$mdata" || |
1121 | { error "failed cloud-localds"; return 1; } |
1122 | - seedargs=( "-drive" "file=${seed},if=virtio,media=cdrom" ) |
1123 | + seedargs=( "--disk=file=${seed},if=virtio,media=cdrom" ) |
1124 | fi |
1125 | |
1126 | local netargs |
1127 | @@ -779,13 +778,14 @@ |
1128 | fi |
1129 | fi |
1130 | # -monitor stdio |
1131 | + local bootdisk="--disk=file=$bootimg,id=boot,index=1,cache=unsafe" |
1132 | cmd=( |
1133 | - xkvm "${pt[@]}" "${netargs[@]}" -- |
1134 | + xkvm "${pt[@]}" "${netargs[@]}" |
1135 | + "$bootdisk" |
1136 | + "${disk_args[@]}" |
1137 | + -- |
1138 | -smp ${smp} |
1139 | -m ${mem} ${serial_args} ${video} |
1140 | - -drive "file=$bootimg,if=none,cache=unsafe,format=qcow2,id=boot,index=0" |
1141 | - -device "virtio-blk,drive=boot" |
1142 | - "${disk_args[@]}" |
1143 | "${seedargs[@]}" |
1144 | ) |
1145 | |
1146 | |
1147 | === modified file 'tools/xkvm' |
1148 | --- tools/xkvm 2016-12-02 02:04:27 +0000 |
1149 | +++ tools/xkvm 2017-11-07 18:32:47 +0000 |
1150 | @@ -11,6 +11,8 @@ |
1151 | # OVS_CLEANUP gets populated with bridge:devname pairs used with ovs |
1152 | OVS_CLEANUP=( ) |
1153 | MAC_PREFIX="52:54:00:12:34" |
1154 | +# allow this to be set externally. |
1155 | +_QEMU_SUPPORTS_FILE_LOCKING="${_QEMU_SUPPORTS_FILE_LOCKING}" |
1156 | KVM="kvm" |
1157 | declare -A KVM_DEVOPTS |
1158 | |
1159 | @@ -119,6 +121,21 @@ |
1160 | return 1 |
1161 | } |
1162 | |
1163 | +qemu_supports_file_locking() { |
1164 | + # hackily check if qemu has file.locking in -drive params (LP: #1716028) |
1165 | + if [ -z "$_QEMU_SUPPORTS_FILE_LOCKING" ]; then |
1166 | + # The only way we could find to check presense of file.locking is |
1167 | + # qmp (query-qmp-schema). Simply checking if the virtio-blk driver |
1168 | + # supports 'share-rw' is expected to be equivalent and simpler. |
1169 | + isdevopt virtio-blk share-rw && |
1170 | + _QEMU_SUPPORTS_FILE_LOCKING=true || |
1171 | + _QEMU_SUPPORTS_FILE_LOCKING=false |
1172 | + debug 1 "qemu supports file locking = ${_QEMU_SUPPORTS_FILE_LOCKING}" |
1173 | + fi |
1174 | + [ "$_QEMU_SUPPORTS_FILE_LOCKING" = "true" ] |
1175 | + return |
1176 | +} |
1177 | + |
1178 | padmac() { |
1179 | # return a full mac, given a subset. |
1180 | # assume whatever is input is the last portion to be |
1181 | @@ -443,7 +460,7 @@ |
1182 | out=$(LANG=C qemu-img info "$file") && |
1183 | fmt=$(echo "$out" | awk '$0 ~ /^file format:/ { print $3 }') || |
1184 | { error "failed to determine format of $file"; return 1; } |
1185 | - else |
1186 | + elif [ -z "$fmt" ]; then |
1187 | fmt=raw |
1188 | fi |
1189 | if [ -z "$driver" ]; then |
1190 | @@ -470,6 +487,12 @@ |
1191 | id=*|if=*|driver=*|$file|file=*) continue;; |
1192 | fmt=*|format=*) continue;; |
1193 | serial=*|bus=*|unit=*|index=*) continue;; |
1194 | + file.locking=*) |
1195 | + qemu_supports_file_locking || { |
1196 | + debug 2 "qemu has no file locking." \ |
1197 | + "Dropping '$tok' from: $cur" |
1198 | + continue |
1199 | + };; |
1200 | esac |
1201 | isdevopt "$driver" "$tok" && devopts="${devopts},$tok" || |
1202 | diskopts="${diskopts},${tok}" |