Merge ~ogayot/curtin:flag-logical+swap into curtin:master

Proposed by Olivier Gayot
Status: Merged
Approved by: Dan Bungert
Approved revision: 3402978ee4b4e8aef5c1ce21dba04c8a9d03f931
Merge reported by: Server Team CI bot
Merged at revision: not available
Proposed branch: ~ogayot/curtin:flag-logical+swap
Merge into: curtin:master
Diff against target: 54 lines (+27/-1)
2 files modified
curtin/commands/block_meta_v2.py (+13/-1)
tests/unittests/test_commands_block_meta.py (+14/-0)
Reviewer Review Type Date Requested Status
Dan Bungert Approve
Server Team CI bot continuous-integration Approve
Review via email: mp+441769@code.launchpad.net

Commit message

block_meta_v2: don't solely expect flag='logical' for logical partitions

Most of the time, a logical partition has its flag set to 'local'.
However, it some cases, it can also have flag set to 'swap', 'boot' and
possibly other values.

To determine if a partition is actually logical on a DOS partition
table, we need to check the partition number.

Description of the change

In block_meta_v2, we expect logical partitions to have their flag set to 'logical'. However, there are valid scenarios where this is a wrong assumption.

One use-case is the creation of a logical swap partition. This partition would end up with flag='swap' and not flag='logical' ; despite being a logical partition.

Despite being an unsupported use-case in Ubuntu, sometimes a bootable ESP partition is a logical partition.
In curtin's storage_config code, we have the following statement:

 # if the boot flag is set, use this as the flag, logical
 # flag is not required as we can determine logical via
 # partition number

https://git.launchpad.net/curtin/tree/curtin/storage_config.py?id=33411a726532d24e982e29c62f48abd82e2bc4fe#n809

To post a comment you must log in.
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Dan Bungert (dbungert) wrote :

Unit test please. I think it's fine to extract this to a utility function to make this easier.

Revision history for this message
Olivier Gayot (ogayot) wrote :

Thanks for the suggestion. Updated!

I've made is_logical(action) a static method so it can be tested with more ease.

Revision history for this message
Olivier Gayot (ogayot) wrote :

NOTE: I've only fixed the code for storage config version 2. Maybe we need to update storage version 1 too.

Revision history for this message
Dan Bungert (dbungert) wrote :

Thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/curtin/commands/block_meta_v2.py b/curtin/commands/block_meta_v2.py
2index 79dfd39..ae0b058 100644
3--- a/curtin/commands/block_meta_v2.py
4+++ b/curtin/commands/block_meta_v2.py
5@@ -248,12 +248,24 @@ class DOSPartTable(SFDiskPartTable):
6 label = 'dos'
7 _extended = None
8
9+ @staticmethod
10+ def is_logical(action) -> bool:
11+ flag = action.get('flag', None)
12+ if flag == 'logical':
13+ return True
14+ # In some scenarios, a swap partition can be in the extended
15+ # partition. When it does, the flag is set to 'swap'.
16+ # In some other scenarios, a bootable partition can also be in the
17+ # extended partition. This is not a supported use-case but is
18+ # yet another scenario where flag is not set to 'logical'.
19+ return action.get('number', 0) > 4
20+
21 def add(self, action):
22 flag = action.get('flag', None)
23 start = action.get('offset', None)
24 if start is not None:
25 start = self.bytes2sectors(start)
26- if flag == 'logical':
27+ if self.is_logical(action):
28 if self._extended is None:
29 raise Exception("logical partition without extended partition")
30 prev = None
31diff --git a/tests/unittests/test_commands_block_meta.py b/tests/unittests/test_commands_block_meta.py
32index 82530ff..dc03359 100644
33--- a/tests/unittests/test_commands_block_meta.py
34+++ b/tests/unittests/test_commands_block_meta.py
35@@ -3259,6 +3259,20 @@ label: dos
36 f'name="{name}" attrs="{attrs}"'
37 self.assertEqual(expected, pte.render())
38
39+ def test_v2_dos_is_logical(self):
40+ action = {"flag": "logical"}
41+ self.assertTrue(block_meta_v2.DOSPartTable.is_logical(action))
42+ action = {"flag": "logical", "number": 5}
43+ self.assertTrue(block_meta_v2.DOSPartTable.is_logical(action))
44+ action = {"flag": "swap", "number": 2}
45+ self.assertFalse(block_meta_v2.DOSPartTable.is_logical(action))
46+ action = {"flag": "swap", "number": 5}
47+ self.assertTrue(block_meta_v2.DOSPartTable.is_logical(action))
48+ action = {"flag": "boot", "number": 5}
49+ self.assertTrue(block_meta_v2.DOSPartTable.is_logical(action))
50+ action = {"flag": "swap"}
51+ self.assertFalse(block_meta_v2.DOSPartTable.is_logical(action))
52+
53
54 class TestPartitionNeedsResize(CiTestCase):
55

Subscribers

People subscribed via source and target branches