Skip to content

Commit

Permalink
Build, do not import dynamically generated classes
Browse files Browse the repository at this point in the history
Signed-off-by: mulhern <[email protected]>
  • Loading branch information
mulkieran committed Nov 27, 2023
1 parent 598199a commit b166f92
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 9 deletions.
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[tool.pylint]
good-names="Manager,ObjectManager,Report"
58 changes: 58 additions & 0 deletions src/stratis_cli/_actions/_dynamic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Copyright 2023 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Dynamic class generation
"""
# isort: STDLIB
import os
import xml.etree.ElementTree as ET # nosec B405
from enum import Enum

# isort: FIRSTPARTY
from dbus_python_client_gen import DPClientGenerationError, make_class

from .._errors import StratisCliGenerationError
from ._constants import MANAGER_INTERFACE, REPORT_INTERFACE
from ._environment import get_timeout
from ._introspect import SPECS

DBUS_TIMEOUT_SECONDS = 120

TIMEOUT = get_timeout(
os.environ.get("STRATIS_DBUS_TIMEOUT", DBUS_TIMEOUT_SECONDS * 1000)
)


class ClassKey(Enum):
"""
Keys for dynamically generated classes.
"""

MANAGER = ("Manager", MANAGER_INTERFACE)
OBJECT_MANAGER = ("ObjectManager", "org.freedesktop.DBUs.ObjectManager")
REPORT = ("Report", REPORT_INTERFACE)


def make_dyn_class(key):
"""
Dynamically generate a class from introspection specification.
"""
try:
return make_class(
key.value[0], ET.fromstring(SPECS[key.value[1]]), TIMEOUT # nosec B314
)
except DPClientGenerationError as err: # pragma: no cover
raise StratisCliGenerationError(
"Failed to generate some class needed for invoking dbus-python methods"
) from err
16 changes: 7 additions & 9 deletions src/stratis_cli/_actions/_top.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from .._stratisd_constants import ReportKey, StratisdErrors
from ._connection import get_object
from ._constants import TOP_OBJECT
from ._dynamic import ClassKey, make_dyn_class
from ._formatting import print_table


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

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

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

if capture_key:
password = getpass(prompt="Enter key data followed by the return key: ")
Expand Down Expand Up @@ -119,22 +118,22 @@ def get_report(namespace):

# pylint: disable=import-outside-toplevel
if namespace.report_name == ReportKey.MANAGED_OBJECTS.value:
from ._data import ObjectManager
ObjectManager = make_dyn_class(ClassKey.OBJECT_MANAGER)

json_report = ObjectManager.Methods.GetManagedObjects(
get_object(TOP_OBJECT), {}
)

else:
if namespace.report_name == ReportKey.ENGINE_STATE.value:
from ._data import Manager
Manager = make_dyn_class(ClassKey.MANAGER)

(report, return_code, message) = Manager.Methods.EngineStateReport(
get_object(TOP_OBJECT), {}
)

else:
from ._data import Report
Report = make_dyn_class(ClassKey.REPORT)

(report, return_code, message) = Report.Methods.GetReport(
get_object(TOP_OBJECT), {"name": namespace.report_name}
Expand Down Expand Up @@ -242,8 +241,7 @@ def unset_key(namespace):
:raises StratisCliNoChangeError:
:raises StratisCliIncoherenceError:
"""
# pylint: disable=import-outside-toplevel
from ._data import Manager
Manager = make_dyn_class(ClassKey.MANAGER)

proxy = get_object(TOP_OBJECT)

Expand Down

0 comments on commit b166f92

Please sign in to comment.