From 9220af325fd362805c91083cec09d5432098ba77 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Thu, 24 Dec 2020 22:03:46 +0800 Subject: [PATCH] ceph.in,ceph_argparse: add type annotations Signed-off-by: Kefu Chai --- src/ceph.in | 27 ++++++++++++++------ src/pybind/ceph_argparse.py | 49 ++++++++++++++++++++++++++++--------- src/pybind/ceph_daemon.py | 5 +++- 3 files changed, 61 insertions(+), 20 deletions(-) diff --git a/src/ceph.in b/src/ceph.in index 1714ae931bb..c2a861bac1c 100755 --- a/src/ceph.in +++ b/src/ceph.in @@ -29,6 +29,8 @@ import sys import time import platform +from typing import Dict, List, Sequence, Tuple + try: input = raw_input except NameError: @@ -257,7 +259,9 @@ GLOBAL_ARGS = { } -def parse_cmdargs(args=None, target=''): +def parse_cmdargs(args=None, target='') -> Tuple[argparse.ArgumentParser, + argparse.Namespace, + List[str]]: """ Consume generic arguments from the start of the ``args`` list. Call this first to handle arguments that are not @@ -374,7 +378,7 @@ daemonperf {type.id | path} list|ls [stat-pats] [priority] """, file=sys.stdout) -def do_extended_help(parser, args, target, partial): +def do_extended_help(parser, args, target, partial) -> int: def help_for_sigs(sigs, partial=None): try: sys.stdout.write(format_help(parse_json_funcsigs(sigs, 'cli'), @@ -458,7 +462,7 @@ def wrap(s, width, indent): yield result -def format_help(cmddict, partial=None): +def format_help(cmddict, partial=None) -> str: """ Formats all the cmdsigs and helptexts from cmddict into a sorted-by- cmdsig 2-column display, with each column wrapped and indented to @@ -604,7 +608,11 @@ def do_command(parsed_args, target, cmdargs, sigdict, inbuf, verbose): return ret, outbuf, outs -def new_style_command(parsed_args, cmdargs, target, sigdict, inbuf, verbose): +def new_style_command(parsed_args, + cmdargs, + target, + sigdict, + inbuf, verbose) -> Tuple[int, bytes, str]: """ Do new-style command dance. target: daemon to receive command: mon (any) or osd.N @@ -803,7 +811,7 @@ def isnum(s): return False -def daemonperf(childargs, sockpath): +def daemonperf(childargs: Sequence[str], sockpath: str): """ Handle daemonperf command; returns errno or 0 @@ -877,7 +885,9 @@ def daemonperf(childargs, sockpath): return 0 -def get_scrub_timestamps(childargs): + +def get_scrub_timestamps(childargs: Sequence[str]) -> Dict[str, + Tuple[str, str]]: last_scrub_stamp = "last_" + childargs[1].replace('-', '_') + "_stamp" results = dict() scruball = False @@ -896,6 +906,7 @@ def get_scrub_timestamps(childargs): results[stat['pgid']] = scrub_tuple return results + def check_scrub_stamps(waitdata, currdata): for pg in waitdata.keys(): # Try to handle the case where a pg may not exist in current results @@ -903,6 +914,7 @@ def check_scrub_stamps(waitdata, currdata): return False return True + def waitscrub(childargs, waitdata): print('Waiting for {0} to complete...'.format(childargs[1]), file=sys.stdout) currdata = get_scrub_timestamps(childargs) @@ -911,7 +923,8 @@ def waitscrub(childargs, waitdata): currdata = get_scrub_timestamps(childargs) print('{0} completed'.format(childargs[1]), file=sys.stdout) -def wait(childargs, waitdata): + +def wait(childargs: Sequence[str], waitdata): if childargs[1] in ['scrub', 'deep-scrub']: waitscrub(childargs, waitdata) diff --git a/src/pybind/ceph_argparse.py b/src/pybind/ceph_argparse.py index 53faf3cbce5..7bb42aa26d5 100644 --- a/src/pybind/ceph_argparse.py +++ b/src/pybind/ceph_argparse.py @@ -23,6 +23,9 @@ import sys import threading import uuid +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + + # Flags are from MonCommand.h class Flag: NOFORWARD = (1 << 0) @@ -755,7 +758,7 @@ def descsort(sh1, sh2): return cmp(descsort_key(sh1), descsort_key(sh2)) -def parse_funcsig(sig): +def parse_funcsig(sig: Sequence[Union[str, Dict[str, str]]]) -> List[argdesc]: """ parse a single descriptor (array of strings or dicts) into a dict of function descriptor/validators (objects of CephXXX type) @@ -798,7 +801,8 @@ def parse_funcsig(sig): return newsig -def parse_json_funcsigs(s, consumer): +def parse_json_funcsigs(s: str, + consumer: str) -> Dict[str, Dict[str, List[argdesc]]]: """ A function signature is mostly an array of argdesc; it's represented in JSON as @@ -907,7 +911,12 @@ def matchnum(args, signature, partial=False): return matchcnt -def store_arg(desc, d): +ValidatedArgs = Dict[str, Union[bool, int, float, str, + Tuple[str, str], + Sequence[str]]] + + +def store_arg(desc: argdesc, d: ValidatedArgs): ''' Store argument described by, and held in, thanks to valid(), desc into the dictionary d, keyed by desc.name. Three cases: @@ -932,7 +941,10 @@ def store_arg(desc, d): d[desc.name] = desc.instance.val -def validate(args, signature, flags=0, partial=False): +def validate(args: List[str], + signature: Sequence[argdesc], + flags: Optional[int] = 0, + partial: Optional[bool] = False) -> ValidatedArgs: """ validate(args, signature, flags=0, partial=False) @@ -1116,7 +1128,9 @@ def validate(args, signature, flags=0, partial=False): return d -def validate_command(sigdict, args, verbose=False): +def validate_command(sigdict: Dict[str, Dict[str, Any]], + args: Sequence[str], + verbose: Optional[bool] = False) -> ValidatedArgs: """ Parse positional arguments into a parameter dict, according to the command descriptions. @@ -1224,7 +1238,7 @@ def validate_command(sigdict, args, verbose=False): return valid_dict -def find_cmd_target(childargs): +def find_cmd_target(childargs: List[str]) -> Tuple[str, str]: """ Using a minimal validation, figure out whether the command should be sent to a monitor or an osd. We do this before even @@ -1307,7 +1321,8 @@ class RadosThread(threading.Thread): self.exception = e -def run_in_thread(func, *args, **kwargs): +def run_in_thread(func: Callable[[Any, Any], int], + *args: Any, **kwargs: Any) -> int: timeout = kwargs.pop('timeout', 0) if timeout == 0 or timeout == None: # python threading module will just get blocked if timeout is `None`, @@ -1340,7 +1355,7 @@ def run_in_thread(func, *args, **kwargs): return t.retval -def send_command_retry(*args, **kwargs): +def send_command_retry(*args: Any, **kwargs: Any) -> Tuple[int, bytes, str]: while True: try: return send_command(*args, **kwargs) @@ -1353,8 +1368,13 @@ def send_command_retry(*args, **kwargs): else: raise -def send_command(cluster, target=('mon', ''), cmd=None, inbuf=b'', timeout=0, - verbose=False): + +def send_command(cluster, + target: Optional[Tuple[str, str]] = ('mon', ''), + cmd: Optional[List[str]] = None, + inbuf: Optional[bytes] = b'', + timeout: Optional[int] = 0, + verbose: Optional[bool] = False) -> Tuple[int, bytes, str]: """ Send a command to a daemon using librados's mon_command, osd_command, mgr_command, or pg_command. Any bulk input data @@ -1449,8 +1469,13 @@ def send_command(cluster, target=('mon', ''), cmd=None, inbuf=b'', timeout=0, return ret, outbuf, outs -def json_command(cluster, target=('mon', ''), prefix=None, argdict=None, - inbuf=b'', timeout=0, verbose=False): +def json_command(cluster, + target: Optional[Tuple[str, str]] = ('mon', ''), + prefix: Optional[str] = None, + argdict: Optional[Dict[str, str]] = None, + inbuf: Optional[bytes] = b'', + timeout: Optional[int] = 0, + verbose: Optional[bool] = False) -> Tuple[int, bytes, str]: """ Serialize a command and up a JSON command and send it with send_command() above. Prefix may be supplied separately or in argdict. Any bulk input diff --git a/src/pybind/ceph_daemon.py b/src/pybind/ceph_daemon.py index 9b55613f5d9..7bbde76c902 100644 --- a/src/pybind/ceph_daemon.py +++ b/src/pybind/ceph_daemon.py @@ -24,6 +24,7 @@ from fnmatch import fnmatch from prettytable import PrettyTable, HEADER from signal import signal, SIGWINCH from termios import TIOCGWINSZ +from typing import Optional from ceph_argparse import parse_json_funcsigs, validate_command @@ -32,7 +33,9 @@ LONG_RUNNING_AVG = 0x4 READ_CHUNK_SIZE = 4096 -def admin_socket(asok_path, cmd, format=''): +def admin_socket(asok_path: str, + cmd: str, + format: Optional[str] = '') -> bytes: """ Send a daemon (--admin-daemon) command 'cmd'. asok_path is the path to the admin socket; cmd is a list of strings; format may be -- 2.39.5