Skip to content

Commit

Permalink
Use dynamic build for Manager class
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 f60cbfb
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 7 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"
56 changes: 56 additions & 0 deletions src/stratis_cli/_actions/_dynamic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# 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
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)


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
12 changes: 5 additions & 7 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 @@ -127,7 +126,7 @@ def get_report(namespace):

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), {}
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 f60cbfb

Please sign in to comment.