From 7ce26be7a34480ac1b0dbf870518310c112dde2d Mon Sep 17 00:00:00 2001 From: Thomas Bechtold Date: Wed, 13 Nov 2019 16:13:20 +0100 Subject: [PATCH] ceph-daemon: Add basic mypy support Add mypy support and some type hints to be able to do static code analysis. Signed-off-by: Thomas Bechtold --- src/ceph-daemon/CMakeLists.txt | 2 +- src/ceph-daemon/ceph-daemon | 46 ++++++++++++++++++---------------- src/ceph-daemon/mypy.ini | 2 ++ src/ceph-daemon/tox.ini | 7 +++++- 4 files changed, 34 insertions(+), 23 deletions(-) create mode 100644 src/ceph-daemon/mypy.ini diff --git a/src/ceph-daemon/CMakeLists.txt b/src/ceph-daemon/CMakeLists.txt index 40e74ba30d399..a83105b2a99cf 100644 --- a/src/ceph-daemon/CMakeLists.txt +++ b/src/ceph-daemon/CMakeLists.txt @@ -1,4 +1,4 @@ if(WITH_TESTS) include(AddCephTest) - add_tox_test(ceph-daemon TOX_ENVS) + add_tox_test(ceph-daemon TOX_ENVS mypy) endif() diff --git a/src/ceph-daemon/ceph-daemon b/src/ceph-daemon/ceph-daemon index 414782f04d479..73366d8a0b7e7 100755 --- a/src/ceph-daemon/ceph-daemon +++ b/src/ceph-daemon/ceph-daemon @@ -53,6 +53,10 @@ import subprocess import sys import tempfile import time +try: + from typing import Tuple, Optional +except ImportError: + pass import uuid from distutils.spawn import find_executable @@ -62,7 +66,7 @@ try: from tempfile import TemporaryDirectory # py3 except ImportError: # define a minimal (but sufficient) equivalent for <= py 3.2 - class TemporaryDirectory(object): + class TemporaryDirectory(object): # type: ignore def __init__(self): self.name = tempfile.mkdtemp() @@ -191,32 +195,32 @@ def call_throws(command, **kwargs): ################################## -def pathify(p): +def pathify(p): # type: (str) -> str if not p.startswith('/'): return os.path.join(os.getcwd(), p) return p -def get_hostname(): +def get_hostname(): # type: () -> str return socket.gethostname() -def get_fqdn(): +def get_fqdn(): # type: () -> str return socket.getfqdn() or socket.gethostname() -def generate_password(): +def generate_password(): # type: () -> str return ''.join(random.choice(string.ascii_lowercase + string.digits) for i in range(10)) -def make_fsid(): +def make_fsid(): # type: () -> str return str(uuid.uuid1()) -def is_fsid(s): +def is_fsid(s): # type: (str) -> bool try: uuid.UUID(s) except ValueError: return False return True -def makedirs(dir, uid, gid, mode): +def makedirs(dir, uid, gid, mode): # type: (str, int, int, int) -> None if not os.path.exists(dir): os.makedirs(dir, mode=mode) else: @@ -224,13 +228,13 @@ def makedirs(dir, uid, gid, mode): os.chown(dir, uid, gid) os.chmod(dir, mode) # the above is masked by umask... -def get_data_dir(fsid, t, n): +def get_data_dir(fsid, t, n): # type: (str, str, int) -> str return os.path.join(args.data_dir, fsid, '%s.%s' % (t, n)) -def get_log_dir(fsid): +def get_log_dir(fsid): # type: (str) -> str return os.path.join(args.log_dir, fsid) -def make_data_dir_base(fsid, uid, gid): +def make_data_dir_base(fsid, uid, gid): # type: (str, int, int) -> str data_dir_base = os.path.join(args.data_dir, fsid) makedirs(data_dir_base, uid, gid, DATA_DIR_MODE) makedirs(os.path.join(data_dir_base, 'crash'), uid, gid, DATA_DIR_MODE) @@ -238,35 +242,35 @@ def make_data_dir_base(fsid, uid, gid): DATA_DIR_MODE) return data_dir_base -def make_data_dir(fsid, daemon_type, daemon_id, uid=None, gid=None): - if not uid: +def make_data_dir(fsid, daemon_type, daemon_id, uid=None, gid=None): # type: (str, str, int, int, int) -> str + if not uid or not gid: (uid, gid) = extract_uid_gid() make_data_dir_base(fsid, uid, gid) data_dir = get_data_dir(fsid, daemon_type, daemon_id) makedirs(data_dir, uid, gid, DATA_DIR_MODE) return data_dir -def make_log_dir(fsid, uid=None, gid=None): - if not uid: +def make_log_dir(fsid, uid=None, gid=None): # type: (str, int, int) -> str + if not uid or not gid: (uid, gid) = extract_uid_gid() log_dir = get_log_dir(fsid) makedirs(log_dir, uid, gid, LOG_DIR_MODE) return log_dir -def find_program(filename): +def find_program(filename): # type: (str) -> str name = find_executable(filename) if name is None: raise ValueError('%s not found' % filename) return name -def get_unit_name(fsid, daemon_type, daemon_id=None): +def get_unit_name(fsid, daemon_type, daemon_id=None): # type (str, str, int) -> str # accept either name or type + id if daemon_id is not None: return 'ceph-%s@%s.%s' % (fsid, daemon_type, daemon_id) else: return 'ceph-%s@%s' % (fsid, daemon_type) -def check_unit(unit_name): +def check_unit(unit_name): # type: (str) -> Tuple[bool, str] # NOTE: we ignore the exit code here because systemctl outputs # various exit codes based on the state of the service, but the # string result is more explicit (and sufficient). @@ -296,7 +300,7 @@ def check_unit(unit_name): state = 'unknown' return (enabled, state) -def get_legacy_config_fsid(cluster, legacy_dir=None): +def get_legacy_config_fsid(cluster, legacy_dir=None): # type: (str, str) -> Optional[str] config_file = '/etc/ceph/%s.conf' % cluster if legacy_dir is not None: config_file = os.path.abspath(legacy_dir + config_file) @@ -466,7 +470,7 @@ def get_container(fsid, daemon_type, daemon_id, privileged=False, cname='ceph-%s-%s.%s' % (fsid, daemon_type, daemon_id), ) -def extract_uid_gid(): +def extract_uid_gid(): # type: () -> Tuple[int, int] out = CephContainer( image=args.image, entrypoint='/usr/bin/grep', @@ -1846,7 +1850,7 @@ def _get_parser(): if __name__ == "__main__": # allow argv to be injected try: - av = injected_argv + av = injected_argv # type: ignore except NameError: av = sys.argv[1:] parser = _get_parser() diff --git a/src/ceph-daemon/mypy.ini b/src/ceph-daemon/mypy.ini new file mode 100644 index 0000000000000..1215375ed9b85 --- /dev/null +++ b/src/ceph-daemon/mypy.ini @@ -0,0 +1,2 @@ +[mypy] +ignore_missing_imports = True \ No newline at end of file diff --git a/src/ceph-daemon/tox.ini b/src/ceph-daemon/tox.ini index 931aee1491af3..9ade4d4300127 100644 --- a/src/ceph-daemon/tox.ini +++ b/src/ceph-daemon/tox.ini @@ -1,8 +1,13 @@ [tox] -envlist = py27, py3 +envlist = py27, py3, mypy [testenv] skipsdist=true skip_install=true deps = pytest commands=pytest {posargs} + +[testenv:mypy] +basepython = python3 +deps = mypy +commands = mypy {posargs:ceph-daemon} \ No newline at end of file -- 2.39.5