Merge ~raharper/curtin:fix/dname-warning-missing-serial into curtin:master

Proposed by Ryan Harper
Status: Merged
Approved by: Ryan Harper
Approved revision: 2443c3613a2d1338b53fbbdcefeb4ac12994fa4d
Merge reported by: Server Team CI bot
Merged at revision: not available
Proposed branch: ~raharper/curtin:fix/dname-warning-missing-serial
Merge into: curtin:master
Diff against target: 116 lines (+49/-12)
2 files modified
curtin/commands/block_meta.py (+4/-2)
tests/unittests/test_make_dname.py (+45/-10)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve
Chad Smith Approve
Review via email: mp+362752@code.launchpad.net

Commit message

dname: relax dname req for disk serial/wwn presence for compatibility

Allow disks without serial/wwn values to have dnames and do not raise
a RuntimeError exception which prevented legacy KVM pods from deploying
as their VM configuration lacked disk serial numbers. Per discussion
in the bug, prefer compatibility with these systems, allow dname to remain
unstable and provide a warning in the install log but do not fail
deployment. Update dname match attributes to: ID_WWN_WITH_EXTENSION,
ID_WWN, ID_SERIAL, ID_SERIAL_SHORT.

LP: #1735839

To post a comment you must log in.
Revision history for this message
Ryan Harper (raharper) wrote :
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Chad Smith (chad.smith) wrote :

+1 assuming we get a valid vmtest run on this.

review: Approve
Revision history for this message
Ryan Harper (raharper) wrote :

Vmtest ran, 2 tests failed, but were due to high load on jenkins:

Ran 4535 tests in 47305.518s

FAILED (SKIP=716, errors=2)
Fri, 08 Feb 2019 05:30:58 +0000: vmtest end [1] in 47310s

I re-ran those two tests (CosmicTestMultipathBasic, CosmicTestMirrorboot)
which passed.

Ran 22 tests in 311.488s

OK
Fri, 08 Feb 2019 15:14:56 +0000: vmtest end [0] in 317s

Revision history for this message
Server Team CI bot (server-team-bot) wrote :

Commit message lints:
 - Line #0 has 3 too many characters. Line starts with: "dname: relax dname requirement"...

review: Needs Fixing
Revision history for this message
Server Team CI bot (server-team-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/curtin/commands/block_meta.py b/curtin/commands/block_meta.py
index dce3924..150bf82 100644
--- a/curtin/commands/block_meta.py
+++ b/curtin/commands/block_meta.py
@@ -242,12 +242,14 @@ def make_dname_byid(path, error_msg=None, info=None):
242 "Disk tag udev rules are only for disks, %s has devtype=%s" %242 "Disk tag udev rules are only for disks, %s has devtype=%s" %
243 (error_msg, devtype))243 (error_msg, devtype))
244244
245 byid_keys = ['ID_SERIAL', 'ID_WWN_WITH_EXTENSION']245 byid_keys = ['ID_WWN_WITH_EXTENSION', 'ID_WWN',
246 'ID_SERIAL', 'ID_SERIAL_SHORT']
246 present = [k for k in byid_keys if info.get(k)]247 present = [k for k in byid_keys if info.get(k)]
247 if not present:248 if not present:
248 raise RuntimeError(249 LOG.warning(
249 "Cannot create disk tag udev rule for %s, "250 "Cannot create disk tag udev rule for %s, "
250 "missing 'serial' or 'wwn' value" % error_msg)251 "missing 'serial' or 'wwn' value" % error_msg)
252 return []
251253
252 return [[compose_udev_equality('ENV{%s}' % k, info[k]) for k in present]]254 return [[compose_udev_equality('ENV{%s}' % k, info[k]) for k in present]]
253255
diff --git a/tests/unittests/test_make_dname.py b/tests/unittests/test_make_dname.py
index 76c7b28..a088660 100644
--- a/tests/unittests/test_make_dname.py
+++ b/tests/unittests/test_make_dname.py
@@ -132,7 +132,7 @@ class TestMakeDname(CiTestCase):
132 block_meta.make_dname('iscsi1', self.storage_config)132 block_meta.make_dname('iscsi1', self.storage_config)
133 mock_util.ensure_dir.assert_called_with(self.rules_d)133 mock_util.ensure_dir.assert_called_with(self.rules_d)
134 self.assertTrue(mock_log.debug.called)134 self.assertTrue(mock_log.debug.called)
135 both_rules = (id_rule_identifiers + wwn_rule_identifiers)135 both_rules = (wwn_rule_identifiers + id_rule_identifiers)
136 mock_util.write_file.assert_called_with(136 mock_util.write_file.assert_called_with(
137 self.rule_file.format(res_dname),137 self.rule_file.format(res_dname),
138 self._content(138 self._content(
@@ -157,10 +157,9 @@ class TestMakeDname(CiTestCase):
157157
158 # disk with no PT_UUID158 # disk with no PT_UUID
159 disk = 'disk_noid'159 disk = 'disk_noid'
160 with self.assertRaises(RuntimeError):160 block_meta.make_dname(disk, self.storage_config)
161 block_meta.make_dname(disk, self.storage_config)161 mock_log.warning.assert_called_with(warning_msg.format(disk))
162 mock_log.warning.assert_called_with(warning_msg.format(disk))162 self.assertFalse(mock_util.write_file.called)
163 self.assertFalse(mock_util.write_file.called)
164163
165 mock_util.subp.side_effect = self._make_mock_subp_blkid(164 mock_util.subp.side_effect = self._make_mock_subp_blkid(
166 '', self.trusty_blkid)165 '', self.trusty_blkid)
@@ -308,8 +307,7 @@ class TestMakeDnameById(CiTestCase):
308 """test dname_byid raises RuntimeError on device without ID or WWN."""307 """test dname_byid raises RuntimeError on device without ID or WWN."""
309 mypath = "/dev/" + self.random_string()308 mypath = "/dev/" + self.random_string()
310 m_udev.return_value = {'DEVTYPE': 'disk'}309 m_udev.return_value = {'DEVTYPE': 'disk'}
311 with self.assertRaises(RuntimeError):310 self.assertEqual([], block_meta.make_dname_byid(mypath))
312 block_meta.make_dname_byid(mypath)
313311
314 @mock.patch('curtin.commands.block_meta.udevadm_info')312 @mock.patch('curtin.commands.block_meta.udevadm_info')
315 def test_udevinfo_not_called_if_info_provided(self, m_udev):313 def test_udevinfo_not_called_if_info_provided(self, m_udev):
@@ -355,7 +353,7 @@ class TestMakeDnameById(CiTestCase):
355 block_meta.make_dname_byid(mypath, info=info))353 block_meta.make_dname_byid(mypath, info=info))
356354
357 def test_disk_with_both_id_wwn(self):355 def test_disk_with_both_id_wwn(self):
358 """test dname_byid returns rules with both ID_SERIAL and ID_WWN"""356 """test dname_byid returns rules with both ID_WWN_* and ID_SERIAL"""
359 mypath = "/dev/" + self.random_string()357 mypath = "/dev/" + self.random_string()
360 myserial = self.random_string()358 myserial = self.random_string()
361 mywwn = self.random_string()359 mywwn = self.random_string()
@@ -363,9 +361,46 @@ class TestMakeDnameById(CiTestCase):
363 'ID_WWN_WITH_EXTENSION': mywwn,361 'ID_WWN_WITH_EXTENSION': mywwn,
364 'DEVNAME': mypath}362 'DEVNAME': mypath}
365 self.assertEqual(363 self.assertEqual(
366 [['ENV{ID_SERIAL}=="%s"' % myserial,364 [[
367 'ENV{ID_WWN_WITH_EXTENSION}=="%s"' % mywwn]],365 'ENV{ID_WWN_WITH_EXTENSION}=="%s"' % mywwn,
366 'ENV{ID_SERIAL}=="%s"' % myserial,
367 ]],
368 block_meta.make_dname_byid(mypath, info=info))
369
370 def test_disk_with_short_ids(self):
371 """test dname_byid returns rules w/ both ID_WWN and ID_SERIAL_SHORT."""
372 mypath = "/dev/" + self.random_string()
373 myserial = self.random_string()
374 mywwn = self.random_string()
375 info = {'DEVTYPE': 'disk', 'ID_SERIAL_SHORT': myserial,
376 'ID_WWN': mywwn,
377 'DEVNAME': mypath}
378 self.assertEqual(
379 [[
380 'ENV{ID_WWN}=="%s"' % mywwn,
381 'ENV{ID_SERIAL_SHORT}=="%s"' % myserial,
382 ]],
368 block_meta.make_dname_byid(mypath, info=info))383 block_meta.make_dname_byid(mypath, info=info))
369384
385 def test_disk_with_all_ids(self):
386 """test dname_byid returns rules w/ all WWN and SERIAL values."""
387 mypath = "/dev/" + self.random_string()
388 myserial_short = self.random_string()
389 myserial = myserial_short + "_" + myserial_short
390 mywwn = self.random_string()
391 mywwn_ext = mywwn + "_" + mywwn
392 info = {'DEVTYPE': 'disk', 'ID_SERIAL_SHORT': myserial_short,
393 'ID_SERIAL': myserial,
394 'ID_WWN': mywwn,
395 'ID_WWN_WITH_EXTENSION': mywwn_ext,
396 'DEVNAME': mypath}
397 self.assertEqual(
398 [[
399 'ENV{ID_WWN_WITH_EXTENSION}=="%s"' % mywwn_ext,
400 'ENV{ID_WWN}=="%s"' % mywwn,
401 'ENV{ID_SERIAL}=="%s"' % myserial,
402 'ENV{ID_SERIAL_SHORT}=="%s"' % myserial_short,
403 ]],
404 block_meta.make_dname_byid(mypath, info=info))
370405
371# vi: ts=4 expandtab syntax=python406# vi: ts=4 expandtab syntax=python

Subscribers

People subscribed via source and target branches