ceph-devstack 0.1.0__py3-none-any.whl → 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ceph_devstack/host.py +26 -4
- ceph_devstack/requirements.py +66 -34
- {ceph_devstack-0.1.0.dist-info → ceph_devstack-0.2.0.dist-info}/METADATA +1 -1
- {ceph_devstack-0.1.0.dist-info → ceph_devstack-0.2.0.dist-info}/RECORD +10 -10
- tests/resources/ceph/test_requirements_ceph.py +10 -18
- tests/test_requirements_core.py +133 -142
- {ceph_devstack-0.1.0.dist-info → ceph_devstack-0.2.0.dist-info}/WHEEL +0 -0
- {ceph_devstack-0.1.0.dist-info → ceph_devstack-0.2.0.dist-info}/entry_points.txt +0 -0
- {ceph_devstack-0.1.0.dist-info → ceph_devstack-0.2.0.dist-info}/licenses/LICENSE +0 -0
- {ceph_devstack-0.1.0.dist-info → ceph_devstack-0.2.0.dist-info}/top_level.txt +0 -0
ceph_devstack/host.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import json
|
|
2
3
|
import logging
|
|
3
4
|
import os
|
|
4
5
|
import pathlib
|
|
@@ -74,12 +75,26 @@ class Host:
|
|
|
74
75
|
|
|
75
76
|
def os_type(self) -> str:
|
|
76
77
|
if not hasattr(self, "_os_type"):
|
|
77
|
-
proc = self.run(["
|
|
78
|
-
assert proc.
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
proc = self.run(["uname"])
|
|
79
|
+
assert proc.wait() == 0, "uname doesn't work?!"
|
|
80
|
+
if (uname_str := proc.stdout.read().decode().strip().lower()) == "linux":
|
|
81
|
+
proc = self.run(["bash", "-c", ". /etc/os-release && echo $ID"])
|
|
82
|
+
assert proc.stdout is not None
|
|
83
|
+
assert proc.wait() == 0, "is /etc/os-release missing?"
|
|
84
|
+
self._os_type = proc.stdout.read().decode().strip().lower()
|
|
85
|
+
else:
|
|
86
|
+
self._os_type = uname_str
|
|
81
87
|
return self._os_type
|
|
82
88
|
|
|
89
|
+
def package_manager(self) -> str | None:
|
|
90
|
+
if self.os_type in ["centos", "rhel", "alma", "rocky", "fedora"]:
|
|
91
|
+
return "dnf"
|
|
92
|
+
elif self.os_type in ["debian", "ubuntu"]:
|
|
93
|
+
return "apt"
|
|
94
|
+
elif self.os_type == "darwin":
|
|
95
|
+
return "brew"
|
|
96
|
+
raise RuntimeError("Can't determine package manager")
|
|
97
|
+
|
|
83
98
|
async def podman_info(self, force: bool = False) -> Dict:
|
|
84
99
|
if force or not hasattr(self, "_podman_info"):
|
|
85
100
|
proc = await self.arun(["podman", "info"])
|
|
@@ -89,6 +104,13 @@ class Host:
|
|
|
89
104
|
self._podman_info = yaml.safe_load(stdout.decode().strip())
|
|
90
105
|
return self._podman_info
|
|
91
106
|
|
|
107
|
+
async def podman_machine_info(self) -> List[Dict]:
|
|
108
|
+
proc = await self.arun(["podman", "machine", "list", "--format", "json"])
|
|
109
|
+
assert proc.stdout is not None
|
|
110
|
+
await proc.wait()
|
|
111
|
+
stdout = await proc.stdout.read()
|
|
112
|
+
return json.loads(stdout)
|
|
113
|
+
|
|
92
114
|
async def selinux_enforcing(self) -> bool:
|
|
93
115
|
proc = await host.arun(["cat", "/sys/fs/selinux/enforce"])
|
|
94
116
|
assert proc.stdout is not None
|
ceph_devstack/requirements.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import shlex
|
|
2
|
-
import sys
|
|
3
2
|
|
|
4
3
|
from pathlib import Path
|
|
5
4
|
from packaging.version import parse as parse_version, Version
|
|
@@ -40,7 +39,7 @@ class FixableRequirement(Requirement):
|
|
|
40
39
|
|
|
41
40
|
async def fix(self) -> bool:
|
|
42
41
|
assert self.fix_cmd, "Attempted to fix without a fix command"
|
|
43
|
-
proc = await self.host.arun(self.fix_cmd)
|
|
42
|
+
proc = await self.host.arun(self.fix_cmd, stream_output=True)
|
|
44
43
|
return await proc.wait() == 0
|
|
45
44
|
|
|
46
45
|
|
|
@@ -48,36 +47,49 @@ class LocalRequirement(Requirement):
|
|
|
48
47
|
host = local_host
|
|
49
48
|
|
|
50
49
|
|
|
51
|
-
class
|
|
50
|
+
class LocalFixableRequirement(FixableRequirement):
|
|
51
|
+
host = local_host
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class PodmanPlatform(LocalFixableRequirement):
|
|
55
|
+
suggest_msg = "podman not found"
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def fix_cmd(self):
|
|
59
|
+
host_os = self.host.os_type()
|
|
60
|
+
if host_os == "darwin":
|
|
61
|
+
return ["brew", "install", "podman"]
|
|
62
|
+
return ["sudo", host.package_manager(), "install", "-y", "podman"]
|
|
63
|
+
|
|
52
64
|
async def check(self):
|
|
53
|
-
result = False
|
|
54
65
|
try:
|
|
55
|
-
|
|
66
|
+
await self.host.podman_info()
|
|
67
|
+
return True
|
|
56
68
|
except FileNotFoundError:
|
|
57
69
|
logger.error("podman not found. Try: dnf install podman")
|
|
58
70
|
return False
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if
|
|
79
|
-
|
|
80
|
-
return
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class PodmanMachinePresent(FixableRequirement):
|
|
74
|
+
suggest_msg = "podman machine (VM) not present"
|
|
75
|
+
fix_cmd = ["podman", "machine", "init", "--now"]
|
|
76
|
+
|
|
77
|
+
async def check(self):
|
|
78
|
+
machine_infos = await host.podman_machine_info()
|
|
79
|
+
if machine_infos and (machine_info := machine_infos[-1]):
|
|
80
|
+
return machine_info.get("Created") is not None
|
|
81
|
+
return False
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class PodmanMachineRunning(LocalFixableRequirement):
|
|
85
|
+
suggest_msg = "podman machine (VM) not running"
|
|
86
|
+
fix_cmd = ["podman", "machine", "start"]
|
|
87
|
+
|
|
88
|
+
async def check(self):
|
|
89
|
+
machine_infos = await host.podman_machine_info()
|
|
90
|
+
if machine_infos and (machine_info := machine_infos[-1]):
|
|
91
|
+
return machine_info.get("Running", False)
|
|
92
|
+
return False
|
|
81
93
|
|
|
82
94
|
|
|
83
95
|
class PodmanGraphDriver(Requirement):
|
|
@@ -150,6 +162,12 @@ class PodmanVersion(Requirement):
|
|
|
150
162
|
|
|
151
163
|
|
|
152
164
|
class PodmanRuntime(Requirement):
|
|
165
|
+
@property
|
|
166
|
+
def fix_cmd(self):
|
|
167
|
+
if self.host.os_type() != "darwin":
|
|
168
|
+
return ["sudo", self.host.package_manager(), "install", "-y", "crun"]
|
|
169
|
+
return []
|
|
170
|
+
|
|
153
171
|
async def check(self):
|
|
154
172
|
podman_info = await self.host.podman_info()
|
|
155
173
|
storage_conf_path = podman_info["store"]["configFile"]
|
|
@@ -194,22 +212,31 @@ class SysctlValue(FixableRequirement):
|
|
|
194
212
|
class PodmanDNSPlugin(FixableRequirement):
|
|
195
213
|
suggest_msg = "Could not find the podman DNS plugin"
|
|
196
214
|
|
|
197
|
-
|
|
215
|
+
@property
|
|
216
|
+
def dns_plugin_path(self):
|
|
217
|
+
os_type = self.host.os_type()
|
|
218
|
+
if os_type in ["ubuntu", "debian"]:
|
|
219
|
+
return "/usr/lib/cni/dnsname"
|
|
220
|
+
return "/usr/libexec/cni/dnsname"
|
|
221
|
+
|
|
222
|
+
@property
|
|
223
|
+
def check_cmd(self):
|
|
224
|
+
return ["test", "-x", self.dns_plugin_path]
|
|
225
|
+
|
|
226
|
+
@property
|
|
227
|
+
def fix_cmd(self):
|
|
198
228
|
os_type = self.host.os_type()
|
|
199
229
|
if os_type == "centos":
|
|
200
|
-
|
|
201
|
-
self.check_cmd = ["test", "-x", dns_plugin_path]
|
|
202
|
-
self.fix_cmd = ["sudo", "dnf", "install", "-y", dns_plugin_path]
|
|
230
|
+
return ["sudo", "dnf", "install", "-y", self.dns_plugin_path]
|
|
203
231
|
elif os_type in ["ubuntu", "debian"]:
|
|
204
|
-
|
|
205
|
-
self.check_cmd = ["test", "-x", dns_plugin_path]
|
|
206
|
-
self.fix_cmd = [
|
|
232
|
+
return [
|
|
207
233
|
"sudo",
|
|
208
234
|
"apt",
|
|
209
235
|
"install",
|
|
210
236
|
"-y",
|
|
211
237
|
"golang-github-containernetworking-plugin-dnsname",
|
|
212
238
|
]
|
|
239
|
+
return []
|
|
213
240
|
|
|
214
241
|
|
|
215
242
|
class FuseOverlayfsPresence(FixableRequirement):
|
|
@@ -234,6 +261,11 @@ class AppArmorProfile(FixableRequirement):
|
|
|
234
261
|
async def check_requirements():
|
|
235
262
|
if not await PodmanPlatform().evaluate():
|
|
236
263
|
return False
|
|
264
|
+
if local_host.os_type() == "darwin":
|
|
265
|
+
if not await PodmanMachinePresent().evaluate():
|
|
266
|
+
return False
|
|
267
|
+
if not await PodmanMachineRunning().evaluate():
|
|
268
|
+
return False
|
|
237
269
|
|
|
238
270
|
result = True
|
|
239
271
|
# kernel and podman versions for native overlay filesystem
|
|
@@ -5,10 +5,10 @@ ceph_devstack/ceph_devstack.te,sha256=68i9sBb1TAEnCJn2JtyM-ECzPSuZck4vKoymcTbptX
|
|
|
5
5
|
ceph_devstack/cli.py,sha256=lSYwXrwfP8D-k60XuwSqhwZSZNKJFFQfvRM-av1rePM,2057
|
|
6
6
|
ceph_devstack/config.toml,sha256=HsxO3FhwZkHomde69QfElztuN8U1bxk7cQk1_iWB4w0,562
|
|
7
7
|
ceph_devstack/exec.py,sha256=gn95GEQttB6xgdWXXvTsxUxcQsx9TUu6PC8QVQ0_Y7w,2674
|
|
8
|
-
ceph_devstack/host.py,sha256=
|
|
8
|
+
ceph_devstack/host.py,sha256=IRLhQaE_jl4VyHLArkqGzYWi3mxT8_sCG6Y7iDol4vU,5456
|
|
9
9
|
ceph_devstack/logging.conf,sha256=bGlswYcL_fz522y9EoKZOLInrSss8D44glNq0FievFY,521
|
|
10
10
|
ceph_devstack/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
ceph_devstack/requirements.py,sha256=
|
|
11
|
+
ceph_devstack/requirements.py,sha256=7Ashf6qfXW1k-L1Gakj5_Q-fPOBEhMQWnh0hIvtUjh0,9980
|
|
12
12
|
ceph_devstack/resources/__init__.py,sha256=D0vhJBU9Pqslq7hg2qreW_ZhndcRIOHZVVUA0zAIeDM,3386
|
|
13
13
|
ceph_devstack/resources/container.py,sha256=suJNOQ9fMRfCnXQwvEZOcg4jnPtrxb-d17a3Y1s1xG0,5388
|
|
14
14
|
ceph_devstack/resources/misc.py,sha256=iGD_3Xsqako-dOZrHJFEJbMWoQIzy7Q_KkEnkdBb8m0,552
|
|
@@ -17,13 +17,13 @@ ceph_devstack/resources/ceph/containers.py,sha256=3QEwkh3I7f3r47SnlnMB-_mU8fYGR0
|
|
|
17
17
|
ceph_devstack/resources/ceph/exceptions.py,sha256=C4ldyEA7Cukp-QUOwL-MnQ8kpgMDIQ6r_JQe0E9q4eM,101
|
|
18
18
|
ceph_devstack/resources/ceph/requirements.py,sha256=ZJt7Eeb5y2bOc7dJN3-15ftAyySi80phD7erBsGdqSU,2691
|
|
19
19
|
ceph_devstack/resources/ceph/utils.py,sha256=6-1sageEiLMcx53KHo_GKlIjaGw3swoZk8cQ-e-tDP0,1276
|
|
20
|
-
ceph_devstack-0.
|
|
20
|
+
ceph_devstack-0.2.0.dist-info/licenses/LICENSE,sha256=bFeYufyeS1qw0W8pkW1Wj09F2itqX7TAGTnA2NIpApU,1067
|
|
21
21
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
22
|
tests/conftest.py,sha256=qulfsMZz3PyAFMdWQ_VWpOFT9L_BiavRax_yQF2Ne24,128
|
|
23
23
|
tests/test_config.py,sha256=RLAjt9DAcAo8GQXgv9dc3Ka3hhtongMs6ioz5YQwKhY,4394
|
|
24
24
|
tests/test_deep_merge.py,sha256=IP9zzCThmhVghl9XjAAiSrKsPdouH3KbEUaKq8n3Soc,2178
|
|
25
25
|
tests/test_parse_args.py,sha256=2JDAT4Id88Ywl5QmiUHqq5IDGm_j5Yl3Kk7pbl3sOEk,7550
|
|
26
|
-
tests/test_requirements_core.py,sha256=
|
|
26
|
+
tests/test_requirements_core.py,sha256=t7dE53E6N3owO1aHd0nLjXGZ9WDGFFUNIQKZQd1jJBY,19985
|
|
27
27
|
tests/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
28
|
tests/resources/test_container.py,sha256=Xc4IGLf0PViSBIhUQXZHZQtRc-uI2R3PyNjU8lpX6BE,9081
|
|
29
29
|
tests/resources/test_misc.py,sha256=dtOAPngMCTE9bYuYjNuxBiRaxvEibXuBq5VwVsWBdnY,1560
|
|
@@ -32,13 +32,13 @@ tests/resources/ceph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
|
|
|
32
32
|
tests/resources/ceph/test_cephdevstack_core.py,sha256=2Zopu-3TkXyj1amQbMG1KpsVXyRDJts73e6TLYNyz3Y,18340
|
|
33
33
|
tests/resources/ceph/test_devstack.py,sha256=PRsEyYy9EKFIiZKkHYZh6vGffIzlZuW9jA9XEt7xz5M,6201
|
|
34
34
|
tests/resources/ceph/test_env_vars.py,sha256=bLTcEJQJSQp0iiJBunPdGHtVQ94KRWSNEkK8HtXZQn0,2741
|
|
35
|
-
tests/resources/ceph/test_requirements_ceph.py,sha256=
|
|
35
|
+
tests/resources/ceph/test_requirements_ceph.py,sha256=VLPHrzt1dLk3RnzjqRY3wyPUQbMspUuW6S_9cAWtpYU,9134
|
|
36
36
|
tests/resources/ceph/test_ssh_keypair.py,sha256=M8Tc1CY9zb_1WaccMSfnSN35tyjR-CblNtTP0s4OsYU,4019
|
|
37
37
|
tests/resources/ceph/test_testnode.py,sha256=wiftdOU058z9IKp5LeUNlv81U9XjojRUI0fYt8mrbgg,1253
|
|
38
38
|
tests/resources/ceph/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
39
|
tests/resources/ceph/fixtures/testnode-config.toml,sha256=XaI4VACYHeshb7LLxN3viKBNxOBLOUpPuwlcQJyQO-U,44
|
|
40
|
-
ceph_devstack-0.
|
|
41
|
-
ceph_devstack-0.
|
|
42
|
-
ceph_devstack-0.
|
|
43
|
-
ceph_devstack-0.
|
|
44
|
-
ceph_devstack-0.
|
|
40
|
+
ceph_devstack-0.2.0.dist-info/METADATA,sha256=6QrXrp1vvd4eAAtp8rmKlzPnh6FdyBD9HLBPW-thmjI,6877
|
|
41
|
+
ceph_devstack-0.2.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
42
|
+
ceph_devstack-0.2.0.dist-info/entry_points.txt,sha256=3cXOGOSb23ATcOZVQFBTY_imM4VFgFddXlYi-m8PA10,57
|
|
43
|
+
ceph_devstack-0.2.0.dist-info/top_level.txt,sha256=NzTr-vAk2OWL08T8PsmfqkJZNEuezF5oaiHCMJBhHPM,20
|
|
44
|
+
ceph_devstack-0.2.0.dist-info/RECORD,,
|
|
@@ -216,15 +216,11 @@ class TestCephDevStackCheckRequirements:
|
|
|
216
216
|
) as MockLoopCtrlWrite,
|
|
217
217
|
patch("ceph_devstack.host.host.selinux_enforcing") as mock_selinux,
|
|
218
218
|
):
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
MockLoopCtrl.return_value = mock_loop_ctrl
|
|
225
|
-
mock_loop_ctrl_write = AsyncMock()
|
|
226
|
-
mock_loop_ctrl_write.evaluate = AsyncMock(return_value=True)
|
|
227
|
-
MockLoopCtrlWrite.return_value = mock_loop_ctrl_write
|
|
219
|
+
MockHasSudo.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
220
|
+
MockLoopCtrl.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
221
|
+
MockLoopCtrlWrite.return_value = AsyncMock(
|
|
222
|
+
evaluate=AsyncMock(return_value=True)
|
|
223
|
+
)
|
|
228
224
|
mock_selinux.return_value = False
|
|
229
225
|
result = await devstack.check_requirements()
|
|
230
226
|
assert result is True
|
|
@@ -247,15 +243,11 @@ class TestCephDevStackCheckRequirements:
|
|
|
247
243
|
patch("ceph_devstack.host.host.selinux_enforcing") as mock_selinux,
|
|
248
244
|
patch("ceph_devstack.host.host.path_exists") as mock_path_exists,
|
|
249
245
|
):
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
MockLoopCtrl.return_value = mock_loop_ctrl
|
|
256
|
-
mock_loop_ctrl_write = AsyncMock()
|
|
257
|
-
mock_loop_ctrl_write.evaluate = AsyncMock(return_value=True)
|
|
258
|
-
MockLoopCtrlWrite.return_value = mock_loop_ctrl_write
|
|
246
|
+
MockHasSudo.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
247
|
+
MockLoopCtrl.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
248
|
+
MockLoopCtrlWrite.return_value = AsyncMock(
|
|
249
|
+
evaluate=AsyncMock(return_value=True)
|
|
250
|
+
)
|
|
259
251
|
mock_selinux.return_value = False
|
|
260
252
|
mock_path_exists.return_value = False
|
|
261
253
|
result = await devstack.check_requirements()
|
tests/test_requirements_core.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import pytest
|
|
3
3
|
from packaging.version import parse as parse_version
|
|
4
|
-
from unittest.mock import AsyncMock, patch
|
|
4
|
+
from unittest.mock import AsyncMock, MagicMock, patch
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
from ceph_devstack import config, requirements
|
|
@@ -17,6 +17,11 @@ def req(cls):
|
|
|
17
17
|
return cls()
|
|
18
18
|
|
|
19
19
|
|
|
20
|
+
@pytest.fixture(scope="class", params=["centos", "ubuntu", "debian"])
|
|
21
|
+
def os_type(request):
|
|
22
|
+
return request.param
|
|
23
|
+
|
|
24
|
+
|
|
20
25
|
class TestRequirement:
|
|
21
26
|
@pytest.fixture(scope="class")
|
|
22
27
|
def cls(self):
|
|
@@ -113,6 +118,73 @@ class TestLocalRequirement:
|
|
|
113
118
|
assert req.host == requirements.local_host
|
|
114
119
|
|
|
115
120
|
|
|
121
|
+
class TestPodmanPlatform:
|
|
122
|
+
@pytest.fixture(scope="class")
|
|
123
|
+
def cls(self):
|
|
124
|
+
return requirements.PodmanPlatform
|
|
125
|
+
|
|
126
|
+
async def test_podman_present(self, cls):
|
|
127
|
+
with (
|
|
128
|
+
patch(
|
|
129
|
+
"ceph_devstack.requirements.PodmanPlatform.host.podman_info"
|
|
130
|
+
) as MockPodmanInfo,
|
|
131
|
+
patch("ceph_devstack.requirements.local_host") as MockLocalHost,
|
|
132
|
+
):
|
|
133
|
+
MockLocalHost.os_type = MagicMock(return_value="darwin")
|
|
134
|
+
MockPodmanInfo.return_value = {}
|
|
135
|
+
req = cls()
|
|
136
|
+
assert await req.check() is True
|
|
137
|
+
|
|
138
|
+
async def test_podman_missing(self, cls):
|
|
139
|
+
with (
|
|
140
|
+
patch(
|
|
141
|
+
"ceph_devstack.requirements.PodmanPlatform.host.podman_info"
|
|
142
|
+
) as MockPodmanInfo,
|
|
143
|
+
patch("ceph_devstack.requirements.local_host") as MockLocalHost,
|
|
144
|
+
):
|
|
145
|
+
MockLocalHost.os_type = MagicMock(return_value="darwin")
|
|
146
|
+
MockPodmanInfo.side_effect = FileNotFoundError
|
|
147
|
+
req = cls()
|
|
148
|
+
assert await req.check() is False
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class TestPodmanMachinePresent:
|
|
152
|
+
@pytest.fixture(scope="class")
|
|
153
|
+
def cls(self):
|
|
154
|
+
return requirements.PodmanMachinePresent
|
|
155
|
+
|
|
156
|
+
@pytest.mark.parametrize(
|
|
157
|
+
"info,success", [[{}, False], [{"Created": "some_timestamp"}, True]]
|
|
158
|
+
)
|
|
159
|
+
async def test_podman_machine_present(self, cls, info, success):
|
|
160
|
+
with patch("ceph_devstack.requirements.host", AsyncMock()) as MockHost:
|
|
161
|
+
MockHost.podman_machine_info = AsyncMock(return_value=[info])
|
|
162
|
+
req = cls()
|
|
163
|
+
assert await req.check() is success
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class TestPodmanMachineRunning:
|
|
167
|
+
@pytest.fixture(scope="class")
|
|
168
|
+
def cls(self):
|
|
169
|
+
return requirements.PodmanMachineRunning
|
|
170
|
+
|
|
171
|
+
@pytest.mark.parametrize(
|
|
172
|
+
"info,success",
|
|
173
|
+
[[{}, False], [{"Running": False}, False], [{"Running": True}, True]],
|
|
174
|
+
)
|
|
175
|
+
async def test_podman_machine_running(self, cls, info, success):
|
|
176
|
+
with patch("ceph_devstack.requirements.host", AsyncMock()) as MockHost:
|
|
177
|
+
MockHost.podman_machine_info = AsyncMock(return_value=[info])
|
|
178
|
+
req = cls()
|
|
179
|
+
assert await req.check() is success
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class TestPodmanRuntime:
|
|
183
|
+
@pytest.fixture(scope="class")
|
|
184
|
+
def cls(self):
|
|
185
|
+
return requirements.PodmanRuntime
|
|
186
|
+
|
|
187
|
+
|
|
116
188
|
class TestPodmanVersionInit:
|
|
117
189
|
@pytest.fixture(scope="class")
|
|
118
190
|
def cls(self):
|
|
@@ -223,10 +295,6 @@ class TestPodmanDNSPluginInit:
|
|
|
223
295
|
def cls(self):
|
|
224
296
|
return requirements.PodmanDNSPlugin
|
|
225
297
|
|
|
226
|
-
@pytest.fixture(scope="class", params=["centos", "ubuntu", "debian"])
|
|
227
|
-
def os_type(self, request):
|
|
228
|
-
return request.param
|
|
229
|
-
|
|
230
298
|
@pytest.fixture(scope="class")
|
|
231
299
|
def dns_plugin_path(self, os_type):
|
|
232
300
|
if os_type == "centos":
|
|
@@ -281,22 +349,25 @@ class TestCheckRequirements:
|
|
|
281
349
|
|
|
282
350
|
async def test_check_requirements_returns_false_on_overlay_failure(self):
|
|
283
351
|
with (
|
|
352
|
+
patch("ceph_devstack.requirements.local_host") as MockLocalHost,
|
|
284
353
|
patch("ceph_devstack.requirements.PodmanPlatform") as MockPlatform,
|
|
285
354
|
patch("ceph_devstack.requirements.PodmanGraphDriver") as MockGraph,
|
|
355
|
+
patch("ceph_devstack.requirements.PodmanVersion") as MockVersion,
|
|
356
|
+
patch("ceph_devstack.requirements.KernelVersionForOverlay") as MockKernel,
|
|
357
|
+
patch("ceph_devstack.requirements.CgroupV2") as MockCgroup,
|
|
286
358
|
):
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
MockGraph.return_value = mock_graph
|
|
294
|
-
|
|
359
|
+
MockLocalHost.os_type = MagicMock(return_value="centos")
|
|
360
|
+
MockPlatform.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
361
|
+
MockGraph.return_value = AsyncMock(evaluate=AsyncMock(return_value=False))
|
|
362
|
+
MockVersion.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
363
|
+
MockKernel.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
364
|
+
MockCgroup.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
295
365
|
result = await requirements.check_requirements()
|
|
296
366
|
assert result is False
|
|
297
367
|
|
|
298
368
|
async def test_check_requirements_returns_true_when_all_pass(self):
|
|
299
369
|
with (
|
|
370
|
+
patch("ceph_devstack.requirements.local_host") as MockLocalHost,
|
|
300
371
|
patch("ceph_devstack.requirements.PodmanPlatform") as MockPlatform,
|
|
301
372
|
patch("ceph_devstack.requirements.PodmanGraphDriver") as MockGraph,
|
|
302
373
|
patch("ceph_devstack.requirements.PodmanVersion") as MockVersion,
|
|
@@ -309,45 +380,24 @@ class TestCheckRequirements:
|
|
|
309
380
|
patch("ceph_devstack.requirements.host.selinux_enforcing") as mock_selinux,
|
|
310
381
|
patch("ceph_devstack.requirements.SysctlValue") as MockSysctl,
|
|
311
382
|
):
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
MockVersion.return_value = mock_version
|
|
323
|
-
|
|
324
|
-
mock_kernel = AsyncMock()
|
|
325
|
-
mock_kernel.evaluate = AsyncMock(return_value=True)
|
|
326
|
-
MockKernel.return_value = mock_kernel
|
|
327
|
-
|
|
328
|
-
mock_cgroup = AsyncMock()
|
|
329
|
-
mock_cgroup.evaluate = AsyncMock(return_value=True)
|
|
330
|
-
MockCgroup.return_value = mock_cgroup
|
|
331
|
-
|
|
332
|
-
mock_kernel_cgroup = AsyncMock()
|
|
333
|
-
mock_kernel_cgroup.evaluate = AsyncMock(return_value=True)
|
|
334
|
-
MockKernelCgroup.return_value = mock_kernel_cgroup
|
|
335
|
-
|
|
336
|
-
mock_runtime = AsyncMock()
|
|
337
|
-
mock_runtime.evaluate = AsyncMock(return_value=True)
|
|
338
|
-
MockRuntime.return_value = mock_runtime
|
|
339
|
-
|
|
383
|
+
MockLocalHost.os_type = MagicMock(return_value="centos")
|
|
384
|
+
MockPlatform.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
385
|
+
MockGraph.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
386
|
+
MockVersion.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
387
|
+
MockKernel.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
388
|
+
MockCgroup.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
389
|
+
MockKernelCgroup.return_value = AsyncMock(
|
|
390
|
+
evaluate=AsyncMock(return_value=True)
|
|
391
|
+
)
|
|
392
|
+
MockRuntime.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
340
393
|
mock_selinux.return_value = False
|
|
341
|
-
|
|
342
|
-
mock_sysctl = AsyncMock()
|
|
343
|
-
mock_sysctl.evaluate = AsyncMock(return_value=True)
|
|
344
|
-
MockSysctl.return_value = mock_sysctl
|
|
345
|
-
|
|
394
|
+
MockSysctl.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
346
395
|
result = await requirements.check_requirements()
|
|
347
396
|
assert result is True
|
|
348
397
|
|
|
349
398
|
async def test_check_requirements_returns_false_on_runtime_failure(self):
|
|
350
399
|
with (
|
|
400
|
+
patch("ceph_devstack.requirements.local_host") as MockLocalHost,
|
|
351
401
|
patch("ceph_devstack.requirements.PodmanPlatform") as MockPlatform,
|
|
352
402
|
patch("ceph_devstack.requirements.PodmanGraphDriver") as MockGraph,
|
|
353
403
|
patch("ceph_devstack.requirements.PodmanVersion") as MockVersion,
|
|
@@ -359,43 +409,26 @@ class TestCheckRequirements:
|
|
|
359
409
|
patch("ceph_devstack.requirements.PodmanRuntime") as MockRuntime,
|
|
360
410
|
patch("ceph_devstack.requirements.host.selinux_enforcing") as mock_selinux,
|
|
361
411
|
):
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
MockGraph.return_value = mock_graph
|
|
369
|
-
|
|
370
|
-
mock_version = AsyncMock()
|
|
371
|
-
mock_version.evaluate = AsyncMock(return_value=True)
|
|
372
|
-
MockVersion.return_value = mock_version
|
|
373
|
-
|
|
374
|
-
mock_kernel = AsyncMock()
|
|
375
|
-
mock_kernel.evaluate = AsyncMock(return_value=True)
|
|
376
|
-
MockKernel.return_value = mock_kernel
|
|
377
|
-
|
|
378
|
-
mock_cgroup = AsyncMock()
|
|
379
|
-
mock_cgroup.evaluate = AsyncMock(return_value=True)
|
|
380
|
-
MockCgroup.return_value = mock_cgroup
|
|
381
|
-
|
|
412
|
+
MockLocalHost.os_type = MagicMock(return_value="centos")
|
|
413
|
+
MockPlatform.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
414
|
+
MockGraph.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
415
|
+
MockVersion.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
416
|
+
MockKernel.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
417
|
+
MockCgroup.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
382
418
|
mock_kernel_cgroup = AsyncMock()
|
|
383
419
|
mock_kernel_cgroup.evaluate = AsyncMock(return_value=True)
|
|
384
420
|
MockKernelCgroup.return_value = mock_kernel_cgroup
|
|
385
|
-
|
|
386
|
-
mock_runtime = AsyncMock()
|
|
387
|
-
mock_runtime.evaluate = AsyncMock(return_value=False)
|
|
388
|
-
MockRuntime.return_value = mock_runtime
|
|
389
|
-
|
|
421
|
+
MockRuntime.return_value = AsyncMock(evaluate=AsyncMock(return_value=False))
|
|
390
422
|
mock_selinux.return_value = False
|
|
391
|
-
|
|
392
423
|
result = await requirements.check_requirements()
|
|
393
424
|
assert result is False
|
|
394
425
|
|
|
395
426
|
async def test_check_requirements_returns_false_on_selinux_bool_failure(self):
|
|
396
427
|
with (
|
|
428
|
+
patch("ceph_devstack.requirements.local_host") as MockLocalHost,
|
|
397
429
|
patch("ceph_devstack.requirements.PodmanPlatform") as MockPlatform,
|
|
398
430
|
patch("ceph_devstack.requirements.PodmanGraphDriver") as MockGraph,
|
|
431
|
+
patch("ceph_devstack.requirements.PodmanVersion") as MockVersion,
|
|
399
432
|
patch("ceph_devstack.requirements.KernelVersionForOverlay") as MockKernel,
|
|
400
433
|
patch("ceph_devstack.requirements.CgroupV2") as MockCgroup,
|
|
401
434
|
patch(
|
|
@@ -405,46 +438,26 @@ class TestCheckRequirements:
|
|
|
405
438
|
patch("ceph_devstack.requirements.host.selinux_enforcing") as mock_selinux,
|
|
406
439
|
patch("ceph_devstack.requirements.SELinuxBoolean") as MockSELinuxBoolean,
|
|
407
440
|
):
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
mock_cgroup = AsyncMock()
|
|
426
|
-
mock_cgroup.evaluate = AsyncMock(return_value=True)
|
|
427
|
-
MockCgroup.return_value = mock_cgroup
|
|
428
|
-
|
|
429
|
-
mock_kernel_cgroup = AsyncMock()
|
|
430
|
-
mock_kernel_cgroup.evaluate = AsyncMock(return_value=True)
|
|
431
|
-
MockKernelCgroup.return_value = mock_kernel_cgroup
|
|
432
|
-
|
|
433
|
-
mock_runtime = AsyncMock()
|
|
434
|
-
mock_runtime.evaluate = AsyncMock(return_value=True)
|
|
435
|
-
MockRuntime.return_value = mock_runtime
|
|
436
|
-
|
|
437
|
-
mock_selinux.return_value = True
|
|
438
|
-
|
|
439
|
-
mock_sel = AsyncMock()
|
|
440
|
-
mock_sel.evaluate = AsyncMock(return_value=False)
|
|
441
|
-
MockSELinuxBoolean.return_value = mock_sel
|
|
442
|
-
|
|
443
|
-
result = await requirements.check_requirements()
|
|
444
|
-
assert result is False
|
|
441
|
+
MockLocalHost.os_type = MagicMock(return_value="centos")
|
|
442
|
+
MockPlatform.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
443
|
+
MockGraph.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
444
|
+
MockVersion.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
445
|
+
MockKernel.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
446
|
+
MockCgroup.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
447
|
+
MockKernelCgroup.return_value = AsyncMock(
|
|
448
|
+
evaluate=AsyncMock(return_value=True)
|
|
449
|
+
)
|
|
450
|
+
MockRuntime.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
451
|
+
mock_selinux.return_value = True
|
|
452
|
+
MockSELinuxBoolean.return_value = AsyncMock(
|
|
453
|
+
evaluate=AsyncMock(return_value=False)
|
|
454
|
+
)
|
|
455
|
+
result = await requirements.check_requirements()
|
|
456
|
+
assert result is False
|
|
445
457
|
|
|
446
458
|
async def test_check_requirements_returns_false_on_sysctl_failure(self):
|
|
447
459
|
with (
|
|
460
|
+
patch("ceph_devstack.requirements.local_host") as MockLocalHost,
|
|
448
461
|
patch("ceph_devstack.requirements.PodmanPlatform") as MockPlatform,
|
|
449
462
|
patch("ceph_devstack.requirements.PodmanGraphDriver") as MockGraph,
|
|
450
463
|
patch("ceph_devstack.requirements.PodmanVersion") as MockVersion,
|
|
@@ -457,39 +470,17 @@ class TestCheckRequirements:
|
|
|
457
470
|
patch("ceph_devstack.requirements.host.selinux_enforcing") as mock_selinux,
|
|
458
471
|
patch("ceph_devstack.requirements.SysctlValue") as MockSysctl,
|
|
459
472
|
):
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
MockVersion.return_value = mock_version
|
|
471
|
-
|
|
472
|
-
mock_kernel = AsyncMock()
|
|
473
|
-
mock_kernel.evaluate = AsyncMock(return_value=True)
|
|
474
|
-
MockKernel.return_value = mock_kernel
|
|
475
|
-
|
|
476
|
-
mock_cgroup = AsyncMock()
|
|
477
|
-
mock_cgroup.evaluate = AsyncMock(return_value=True)
|
|
478
|
-
MockCgroup.return_value = mock_cgroup
|
|
479
|
-
|
|
480
|
-
mock_kernel_cgroup = AsyncMock()
|
|
481
|
-
mock_kernel_cgroup.evaluate = AsyncMock(return_value=True)
|
|
482
|
-
MockKernelCgroup.return_value = mock_kernel_cgroup
|
|
483
|
-
|
|
484
|
-
mock_runtime = AsyncMock()
|
|
485
|
-
mock_runtime.evaluate = AsyncMock(return_value=True)
|
|
486
|
-
MockRuntime.return_value = mock_runtime
|
|
487
|
-
|
|
473
|
+
MockLocalHost.os_type = MagicMock(return_value="centos")
|
|
474
|
+
MockPlatform.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
475
|
+
MockGraph.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
476
|
+
MockVersion.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
477
|
+
MockKernel.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
478
|
+
MockCgroup.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
479
|
+
MockKernelCgroup.return_value = AsyncMock(
|
|
480
|
+
evaluate=AsyncMock(return_value=True)
|
|
481
|
+
)
|
|
482
|
+
MockRuntime.return_value = AsyncMock(evaluate=AsyncMock(return_value=True))
|
|
488
483
|
mock_selinux.return_value = False
|
|
489
|
-
|
|
490
|
-
mock_sysctl = AsyncMock()
|
|
491
|
-
mock_sysctl.evaluate = AsyncMock(return_value=False)
|
|
492
|
-
MockSysctl.return_value = mock_sysctl
|
|
493
|
-
|
|
484
|
+
MockSysctl.return_value = AsyncMock(evaluate=AsyncMock(return_value=False))
|
|
494
485
|
result = await requirements.check_requirements()
|
|
495
486
|
assert result is False
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|