From: Kefu Chai Date: Fri, 29 Jan 2021 16:48:36 +0000 (+0800) Subject: pybind/mgr/hello: add typing annotation X-Git-Tag: v17.1.0~3077^2~20 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=5ca4bc83611a2f018ea722f9c63b0e8f009131ef;p=ceph.git pybind/mgr/hello: add typing annotation also, use Option and CLIReadCommand to define options and cli commands. this module serves as a "hello world" example for developers of mgr modules. so it's important to use the more convenient and safer way to implement the module Signed-off-by: Kefu Chai --- diff --git a/src/mypy.ini b/src/mypy.ini index a10f9e4b3f26..afdb6d528e5b 100755 --- a/src/mypy.ini +++ b/src/mypy.ini @@ -30,6 +30,9 @@ disallow_untyped_defs = True [mypy-devicehealth.*] disallow_untyped_defs = True +[mypy-hello.*] +disallow_untyped_defs = True + [mypy-iostat.*] disallow_untyped_defs = True diff --git a/src/pybind/mgr/hello/module.py b/src/pybind/mgr/hello/module.py index b164dfb620d0..395a1bee1584 100644 --- a/src/pybind/mgr/hello/module.py +++ b/src/pybind/mgr/hello/module.py @@ -5,27 +5,13 @@ A hello world module See doc/mgr/hello.rst for more info. """ -from mgr_module import MgrModule, HandleCommandResult +from mgr_module import CLIReadCommand, HandleCommandResult, MgrModule, Option from threading import Event +from typing import cast, Any, Optional, TYPE_CHECKING import errno -class Hello(MgrModule): - # these are CLI commands we implement - COMMANDS = [ - { - "cmd": "hello " - "name=person_name,type=CephString,req=false", - "desc": "Say hello", - "perm": "r" - }, - { - "cmd": "count " - "name=num,type=CephInt", - "desc": "Do some counting", - "perm": "r" - }, - ] +class Hello(MgrModule): # These are module options we understand. These can be set with # # ceph config set global mgr/hello/ @@ -35,26 +21,20 @@ class Hello(MgrModule): # ceph config set global mgr/hello/place Earth # MODULE_OPTIONS = [ - { - 'name': 'place', - 'default': 'world', - 'desc': 'a place in the world', - 'runtime': True, # can be updated at runtime (no mgr restart) - }, - { - 'name': 'emphatic', - 'type': 'bool', - 'desc': 'whether to say it loudly', - 'default': True, - 'runtime': True, - }, - { - 'name': 'foo', - 'type': 'enum', - 'enum_allowed': [ 'a', 'b', 'c' ], - 'default': 'a', - 'runtime': True, - }, + Option(name='place', + default='world', + desc='a place in the world', + runtime=True), # can be updated at runtime (no mgr restart) + Option(name='emphatic', + type='bool', + desc='whether to say it loudly', + default=True, + runtime=True), + Option(name='foo', + type='str', + enum_allowed=['a', 'b', 'c'], + default='a', + runtime=True) ] # These are "native" Ceph options that this module cares about. @@ -62,8 +42,8 @@ class Hello(MgrModule): 'mgr_tick_period', ] - def __init__(self, *args, **kwargs): - super(Hello, self).__init__(*args, **kwargs) + def __init__(self, *args: Any, **kwargs: Any): + super().__init__(*args, **kwargs) # set up some members to enable the serve() method and shutdown() self.run = True @@ -72,8 +52,11 @@ class Hello(MgrModule): # ensure config options members are initialized; see config_notify() self.config_notify() + # for mypy which does not run the code + if TYPE_CHECKING: + self.mgr_tick_period = 0 - def config_notify(self): + def config_notify(self) -> None: """ This method is called whenever one of our config options is changed. """ @@ -93,34 +76,43 @@ class Hello(MgrModule): self.get_ceph_option(opt)) self.log.debug(' native option %s = %s', opt, getattr(self, opt)) - def handle_command(self, inbuf, cmd): + # there are CLI commands we implement + @CLIReadCommand('hello') + def hello(self, person_name: Optional[str] = None) -> HandleCommandResult: + """ + Say hello + """ + out = '' + if person_name is None: + out = 'Hello, ' + cast(str, self.get_module_option('place')) + else: + out = f'Hello, {person_name}' + if self.get_module_option('emphatic'): + out += '!' + return HandleCommandResult(stdout=out) + + @CLIReadCommand('count') + def count(self, num: int) -> HandleCommandResult: + """ + Do some counting + """ ret = 0 out = '' err = '' - if cmd['prefix'] == 'hello': - if 'person_name' in cmd: - out = "Hello, " + cmd['person_name'] - else: - out = "Hello " + self.get_module_option('place') - if self.get_module_option('emphatic'): - out += '!' - elif cmd['prefix'] == 'count': - num = cmd.get('num', 0) - if num < 1: - err = 'That\'s too small a number' - ret = -errno.EINVAL - elif num > 10: - err = 'That\'s too big a number' - ret = -errno.EINVAL - else: - out = 'Hello, I am the count!\n' - out += ', '.join([str(x) for x in range(1, num + 1)]) + '!' - return HandleCommandResult( - retval=ret, # exit code - stdout=out, # stdout - stderr=err) - - def serve(self): + if num < 1: + err = 'That\'s too small a number' + ret = -errno.EINVAL + elif num > 10: + err = 'That\'s too big a number' + ret = -errno.EINVAL + else: + out = 'Hello, I am the count!\n' + out += ', '.join([str(x) for x in range(1, num + 1)]) + '!' + return HandleCommandResult(retval=ret, + stdout=out, + stderr=err) + + def serve(self) -> None: """ This method is called by the mgr when the module starts and can be used for any background activity. @@ -134,10 +126,10 @@ class Hello(MgrModule): # would presumably have some more appropriate frequency. sleep_interval = self.mgr_tick_period self.log.debug('Sleeping for %d seconds', sleep_interval) - ret = self.event.wait(sleep_interval) + self.event.wait(sleep_interval) self.event.clear() - def shutdown(self): + def shutdown(self) -> None: """ This method is called by the mgr when the module needs to shut down (i.e., when the serve() function needs to exit). diff --git a/src/pybind/mgr/tox.ini b/src/pybind/mgr/tox.ini index baa45111b7ea..b0916a2299e1 100644 --- a/src/pybind/mgr/tox.ini +++ b/src/pybind/mgr/tox.ini @@ -59,6 +59,7 @@ commands = -m cephadm \ -m dashboard \ -m devicehealth \ + -m hello \ -m iostat \ -m mds_autoscaler \ -m mgr_module \