Merge ~dbungert/curtin:zpool-disable-features into curtin:master

Proposed by Dan Bungert
Status: Merged
Merge reported by: Dan Bungert
Merged at revision: 1cc0ec1eb3c5cc0617d6df7320291f706f1804bd
Proposed branch: ~dbungert/curtin:zpool-disable-features
Merge into: curtin:master
Diff against target: 176 lines (+71/-0)
9 files modified
curtin/block/schemas.py (+1/-0)
curtin/block/zfs.py (+5/-0)
curtin/commands/block_meta.py (+2/-0)
doc/topics/storage.rst (+8/-0)
tests/unittests/schema/storage/bad/zpool-default-features.yaml (+8/-0)
tests/unittests/schema/storage/good/zpool-default-features.yaml (+8/-0)
tests/unittests/test_block_zfs.py (+20/-0)
tests/unittests/test_commands_block_meta.py (+1/-0)
tests/unittests/test_schemas.py (+18/-0)
Reviewer Review Type Date Requested Status
Michael Hudson-Doyle Approve
Server Team CI bot continuous-integration Approve
Review via email: mp+448309@code.launchpad.net

Commit message

zpool: add default_features flag support

And a new test type for validating storage configs.

To post a comment you must log in.
Revision history for this message
Dan Bungert (dbungert) wrote :

actually I want to invert this so the field name is default_features, will follow up tomorrow

Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

Flipping this around to avoid the double negatives sounds like a good thing, this looks ok otherwise though.

Revision history for this message
Michael Hudson-Doyle (mwhudson) :
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (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 :

I'm glad we inverted the name because I was definitely confused while writing it, but I think it's correct now.

Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

Yeah this is much cleaner.

Revision history for this message
Michael Hudson-Doyle (mwhudson) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/curtin/block/schemas.py b/curtin/block/schemas.py
2index 514f791..6a5c5b4 100644
3--- a/curtin/block/schemas.py
4+++ b/curtin/block/schemas.py
5@@ -391,6 +391,7 @@ ZPOOL = {
6 'pool': {'$ref': '#/definitions/name'},
7 'pool_properties': {'$ref': '#/definitions/params'},
8 'fs_properties': {'$ref': '#/definitions/params'},
9+ 'default_features': {'type': 'boolean'},
10 'mountpoint': {
11 'type': 'string',
12 'oneOf': [
13diff --git a/curtin/block/zfs.py b/curtin/block/zfs.py
14index 25751d3..2d13d6b 100644
15--- a/curtin/block/zfs.py
16+++ b/curtin/block/zfs.py
17@@ -107,6 +107,7 @@ def zfs_assert_supported():
18
19
20 def zpool_create(poolname, vdevs, mountpoint=None, altroot=None,
21+ default_features=True,
22 pool_properties=None, zfs_properties=None):
23 """
24 Create a zpool called <poolname> comprised of devices specified in <vdevs>.
25@@ -114,6 +115,7 @@ def zpool_create(poolname, vdevs, mountpoint=None, altroot=None,
26 :param poolname: String used to name the pool.
27 :param vdevs: An iterable of strings of block devices paths which *should*
28 start with '/dev/disk/by-id/' to follow best practices.
29+ :param default_features: If true, keep the default features enabled.
30 :param pool_properties: A dictionary of key, value pairs to be passed
31 to `zpool create` with the `-o` flag as properties
32 of the zpool. If value is None, then
33@@ -155,6 +157,9 @@ def zpool_create(poolname, vdevs, mountpoint=None, altroot=None,
34 if altroot:
35 options.extend(['-R', altroot])
36
37+ if not default_features:
38+ options.extend(['-d'])
39+
40 cmd = ["zpool", "create"] + options + [poolname] + vdevs
41 util.subp(cmd, capture=True)
42
43diff --git a/curtin/commands/block_meta.py b/curtin/commands/block_meta.py
44index 11972b9..dd6992d 100644
45--- a/curtin/commands/block_meta.py
46+++ b/curtin/commands/block_meta.py
47@@ -1979,6 +1979,7 @@ def zpool_handler(info, storage_config, context):
48 mountpoint = info.get('mountpoint')
49 pool_properties = info.get('pool_properties', {})
50 fs_properties = info.get('fs_properties', {})
51+ default_features = info.get('default_features', True)
52 altroot = state['target']
53
54 if not vdevs or not poolname:
55@@ -1999,6 +2000,7 @@ def zpool_handler(info, storage_config, context):
56 LOG.info('Creating zpool %s with vdevs %s', poolname, vdevs_byid)
57 zfs.zpool_create(poolname, vdevs_byid,
58 mountpoint=mountpoint, altroot=altroot,
59+ default_features=default_features,
60 pool_properties=pool_properties,
61 zfs_properties=fs_properties)
62
63diff --git a/doc/topics/storage.rst b/doc/topics/storage.rst
64index 918f3cd..67657c1 100644
65--- a/doc/topics/storage.rst
66+++ b/doc/topics/storage.rst
67@@ -1121,6 +1121,14 @@ are:
68 - canmount: off
69 - normalization: formD
70
71+**default_features**: *true, false*
72+
73+If *true*, keep the default features enabled. For fine-grained control of the
74+desired features, set to *false* and enable the desired features with
75+pool_properties. This controls the presence or absence of the `-d` flag of
76+`zpool create`. Default value is *true*, which means the zpool default feature
77+set is used.
78+
79 **Config Example**::
80
81 - type: zpool
82diff --git a/tests/unittests/schema/storage/bad/zpool-default-features.yaml b/tests/unittests/schema/storage/bad/zpool-default-features.yaml
83new file mode 100644
84index 0000000..5f8e74f
85--- /dev/null
86+++ b/tests/unittests/schema/storage/bad/zpool-default-features.yaml
87@@ -0,0 +1,8 @@
88+storage:
89+ version: 2
90+ config:
91+ - type: zpool
92+ id: zpool-1
93+ pool: mypool
94+ vdevs: [/dev/sda]
95+ default_features: 0
96diff --git a/tests/unittests/schema/storage/good/zpool-default-features.yaml b/tests/unittests/schema/storage/good/zpool-default-features.yaml
97new file mode 100644
98index 0000000..1d0a69d
99--- /dev/null
100+++ b/tests/unittests/schema/storage/good/zpool-default-features.yaml
101@@ -0,0 +1,8 @@
102+storage:
103+ version: 2
104+ config:
105+ - type: zpool
106+ id: zpool-1
107+ pool: mypool
108+ vdevs: [/dev/sda]
109+ default_features: false
110diff --git a/tests/unittests/test_block_zfs.py b/tests/unittests/test_block_zfs.py
111index 72cfd3f..2f78863 100644
112--- a/tests/unittests/test_block_zfs.py
113+++ b/tests/unittests/test_block_zfs.py
114@@ -210,6 +210,26 @@ class TestBlockZfsZpoolCreate(CiTestCase):
115 self.assertEqual(sorted(expected_args[index]), sorted(args[0]))
116 self.assertEqual(expected_kwargs, kwargs)
117
118+ def test_zpool_default_features_absent(self):
119+ """ when default_features is missing, no -d arg in zpool create """
120+ zfs.zpool_create('mypool', ['/dev/disk/by-id/virtio-abcfoo1'])
121+ _name, args, _ = self.mock_subp.mock_calls[0]
122+ self.assertNotIn('-d', args[0])
123+
124+ def test_zpool_default_features_true(self):
125+ """ when default_features is true, no -d arg in zpool create """
126+ zfs.zpool_create('mypool', ['/dev/disk/by-id/virtio-abcfoo1'],
127+ default_features=True)
128+ _name, args, _ = self.mock_subp.mock_calls[0]
129+ self.assertNotIn('-d', args[0])
130+
131+ def test_zpool_default_features_false(self):
132+ """ when default_features is false, -d arg in zpool create """
133+ zfs.zpool_create('mypool', ['/dev/disk/by-id/virtio-abcfoo1'],
134+ default_features=False)
135+ _name, args, _ = self.mock_subp.mock_calls[0]
136+ self.assertIn('-d', args[0])
137+
138
139 class TestBlockZfsZfsCreate(CiTestCase):
140
141diff --git a/tests/unittests/test_commands_block_meta.py b/tests/unittests/test_commands_block_meta.py
142index 6388e0b..87e46eb 100644
143--- a/tests/unittests/test_commands_block_meta.py
144+++ b/tests/unittests/test_commands_block_meta.py
145@@ -933,6 +933,7 @@ class TestZpoolHandler(CiTestCase):
146 info['pool'], [disk_path],
147 mountpoint="/",
148 altroot="mytarget",
149+ default_features=True,
150 pool_properties={'ashift': 42},
151 zfs_properties={'compression': 'lz4'})
152
153diff --git a/tests/unittests/test_schemas.py b/tests/unittests/test_schemas.py
154new file mode 100644
155index 0000000..1422ce6
156--- /dev/null
157+++ b/tests/unittests/test_schemas.py
158@@ -0,0 +1,18 @@
159+# This file is part of curtin. See LICENSE file for copyright and license info.
160+
161+import glob
162+import unittest
163+
164+from parameterized import parameterized
165+
166+from curtin.commands.schema_validate import schema_validate_storage
167+
168+
169+class TestSchemaValidation(unittest.TestCase):
170+ @parameterized.expand(glob.glob("tests/unittests/schema/storage/good/*"))
171+ def test_storage_good(self, filename):
172+ self.assertEqual(0, schema_validate_storage(filename))
173+
174+ @parameterized.expand(glob.glob("tests/unittests/schema/storage/bad/*"))
175+ def test_storage_bad(self, filename):
176+ self.assertEqual(1, schema_validate_storage(filename))

Subscribers

People subscribed via source and target branches