Skip to content

Commit f60cbfb

Browse files
committed
Use dynamic build for Manager class
Signed-off-by: mulhern <[email protected]>
1 parent 598199a commit f60cbfb

File tree

3 files changed

+64
-7
lines changed

3 files changed

+64
-7
lines changed

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[build-system]
22
requires = ["setuptools"]
33
build-backend = "setuptools.build_meta"
4+
5+
[tool.pylint]
6+
good-names="Manager"

src/stratis_cli/_actions/_dynamic.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Copyright 2023 Red Hat, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""
15+
Dynamic class generation
16+
"""
17+
# isort: STDLIB
18+
import os
19+
import xml.etree.ElementTree as ET # nosec B405
20+
from enum import Enum
21+
22+
# isort: FIRSTPARTY
23+
from dbus_python_client_gen import DPClientGenerationError, make_class
24+
25+
from .._errors import StratisCliGenerationError
26+
from ._constants import MANAGER_INTERFACE
27+
from ._environment import get_timeout
28+
from ._introspect import SPECS
29+
30+
DBUS_TIMEOUT_SECONDS = 120
31+
32+
TIMEOUT = get_timeout(
33+
os.environ.get("STRATIS_DBUS_TIMEOUT", DBUS_TIMEOUT_SECONDS * 1000)
34+
)
35+
36+
37+
class ClassKey(Enum):
38+
"""
39+
Keys for dynamically generated classes.
40+
"""
41+
42+
MANAGER = ("Manager", MANAGER_INTERFACE)
43+
44+
45+
def make_dyn_class(key):
46+
"""
47+
Dynamically generate a class from introspection specification.
48+
"""
49+
try:
50+
return make_class(
51+
key.value[0], ET.fromstring(SPECS[key.value[1]]), TIMEOUT # nosec B314
52+
)
53+
except DPClientGenerationError as err: # pragma: no cover
54+
raise StratisCliGenerationError(
55+
"Failed to generate some class needed for invoking dbus-python methods"
56+
) from err

src/stratis_cli/_actions/_top.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
from .._stratisd_constants import ReportKey, StratisdErrors
3434
from ._connection import get_object
3535
from ._constants import TOP_OBJECT
36+
from ._dynamic import ClassKey, make_dyn_class
3637
from ._formatting import print_table
3738

3839

@@ -44,8 +45,7 @@ def _fetch_keylist(proxy):
4445
:rtype: list of str
4546
:raises StratisCliEngineError:
4647
"""
47-
# pylint: disable=import-outside-toplevel
48-
from ._data import Manager
48+
Manager = make_dyn_class(ClassKey.MANAGER)
4949

5050
(keys, return_code, message) = Manager.Methods.ListKeys(proxy, {})
5151
if return_code != StratisdErrors.OK: # pragma: no cover
@@ -68,8 +68,7 @@ def _add_update_key(proxy, key_desc, capture_key, *, keyfile_path):
6868
"""
6969
assert capture_key == (keyfile_path is None)
7070

71-
# pylint: disable=import-outside-toplevel
72-
from ._data import Manager
71+
Manager = make_dyn_class(ClassKey.MANAGER)
7372

7473
if capture_key:
7574
password = getpass(prompt="Enter key data followed by the return key: ")
@@ -127,7 +126,7 @@ def get_report(namespace):
127126

128127
else:
129128
if namespace.report_name == ReportKey.ENGINE_STATE.value:
130-
from ._data import Manager
129+
Manager = make_dyn_class(ClassKey.MANAGER)
131130

132131
(report, return_code, message) = Manager.Methods.EngineStateReport(
133132
get_object(TOP_OBJECT), {}
@@ -242,8 +241,7 @@ def unset_key(namespace):
242241
:raises StratisCliNoChangeError:
243242
:raises StratisCliIncoherenceError:
244243
"""
245-
# pylint: disable=import-outside-toplevel
246-
from ._data import Manager
244+
Manager = make_dyn_class(ClassKey.MANAGER)
247245

248246
proxy = get_object(TOP_OBJECT)
249247

0 commit comments

Comments
 (0)