From 906fa6da4a602d097b740a4d0146bef2d8dd5c59 Mon Sep 17 00:00:00 2001 From: Volker Theile Date: Thu, 9 Jul 2020 11:16:42 +0200 Subject: [PATCH] cephadm: Fix Python formating issues Fix obvious Python formating errors reported by my IDE. Signed-off-by: Volker Theile --- src/cephadm/cephadm | 171 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 132 insertions(+), 39 deletions(-) diff --git a/src/cephadm/cephadm b/src/cephadm/cephadm index dad1a361f2f15..a2fc0d97c534e 100755 --- a/src/cephadm/cephadm +++ b/src/cephadm/cephadm @@ -1,21 +1,21 @@ #!/usr/bin/python3 -DEFAULT_IMAGE='docker.io/ceph/daemon-base:latest-master-devel' -DEFAULT_IMAGE_IS_MASTER=True -LATEST_STABLE_RELEASE='octopus' -DATA_DIR='/var/lib/ceph' -LOG_DIR='/var/log/ceph' -LOCK_DIR='/run/cephadm' -LOGROTATE_DIR='/etc/logrotate.d' -UNIT_DIR='/etc/systemd/system' -LOG_DIR_MODE=0o770 -DATA_DIR_MODE=0o700 +DEFAULT_IMAGE = 'docker.io/ceph/daemon-base:latest-master-devel' +DEFAULT_IMAGE_IS_MASTER = True +LATEST_STABLE_RELEASE = 'octopus' +DATA_DIR = '/var/lib/ceph' +LOG_DIR = '/var/log/ceph' +LOCK_DIR = '/run/cephadm' +LOGROTATE_DIR = '/etc/logrotate.d' +UNIT_DIR = '/etc/systemd/system' +LOG_DIR_MODE = 0o770 +DATA_DIR_MODE = 0o700 CONTAINER_PREFERENCE = ['podman', 'docker'] # prefer podman to docker -CUSTOM_PS1=r'[ceph: \u@\h \W]\$ ' -DEFAULT_TIMEOUT=None # in seconds -DEFAULT_RETRY=10 -SHELL_DEFAULT_CONF='/etc/ceph/ceph.conf' -SHELL_DEFAULT_KEYRING='/etc/ceph/ceph.client.admin.keyring' +CUSTOM_PS1 = r'[ceph: \u@\h \W]\$ ' +DEFAULT_TIMEOUT = None # in seconds +DEFAULT_RETRY = 10 +SHELL_DEFAULT_CONF = '/etc/ceph/ceph.conf' +SHELL_DEFAULT_KEYRING = '/etc/ceph/ceph.client.admin.keyring' """ You can invoke cephadm in two ways: @@ -98,20 +98,24 @@ class termcolor: red = '\033[31m' end = '\033[0m' + class Error(Exception): pass + class TimeoutExpired(Error): pass ################################## + class Ceph(object): daemons = ('mon', 'mgr', 'mds', 'osd', 'rgw', 'rbd-mirror', 'crash') ################################## + class Monitoring(object): """Define the configs for the monitoring containers""" @@ -172,6 +176,7 @@ class Monitoring(object): ################################## + class NFSGanesha(object): """Defines a NFS-Ganesha container""" @@ -330,19 +335,20 @@ class NFSGanesha(object): volume_mounts = self.get_container_mounts(data_dir) envs = self.get_container_envs() - logger.info('Creating RADOS grace for action: %s' % (action)) + logger.info('Creating RADOS grace for action: %s' % action) c = CephContainer( image=self.image, entrypoint=entrypoint, args=args, volume_mounts=volume_mounts, - cname=self.get_container_name(desc='grace-%s' % (action)), + cname=self.get_container_name(desc='grace-%s' % action), envs=envs ) return c ################################## + class CephIscsi(object): """Defines a Ceph-Iscsi container""" @@ -479,6 +485,7 @@ class CephIscsi(object): ################################## + def get_supported_daemons(): # type: () -> List[str] supported_daemons = list(Ceph.daemons) @@ -490,6 +497,7 @@ def get_supported_daemons(): ################################## + def attempt_bind(s, address, port): # type: (socket.socket, str, int) -> None try: @@ -505,6 +513,7 @@ def attempt_bind(s, address, port): finally: s.close() + def port_in_use(port_num): # type: (int) -> bool """Detect whether a port is in use on the local machine - IPv4 and IPv6""" @@ -520,6 +529,7 @@ def port_in_use(port_num): else: return False + def check_ip_port(ip, port): # type: (str, int) -> None if not args.skip_ping_check: @@ -546,6 +556,7 @@ try: except NameError: TimeoutError = OSError + class Timeout(TimeoutError): """ Raised when the lock could not be acquired in *timeout* @@ -579,7 +590,7 @@ class _Acquire_ReturnProxy(object): class FileLock(object): - def __init__(self, name, timeout = -1): + def __init__(self, name, timeout=-1): if not os.path.exists(LOCK_DIR): os.mkdir(LOCK_DIR, 0o700) self._lock_file = os.path.join(LOCK_DIR, name + '.lock') @@ -659,14 +670,14 @@ class FileLock(object): lock_id, lock_filename, poll_intervall ) time.sleep(poll_intervall) - except: + except: # noqa # Something did go wrong, so decrement the counter. self._lock_counter = max(0, self._lock_counter - 1) raise return _Acquire_ReturnProxy(lock = self) - def release(self, force = False): + def release(self, force=False): """ Releases the file lock. Please note, that the lock is only completly released, if the lock @@ -699,10 +710,9 @@ class FileLock(object): return None def __del__(self): - self.release(force = True) + self.release(force=True) return None - def _acquire(self): open_mode = os.O_RDWR | os.O_CREAT | os.O_TRUNC fd = os.open(self._lock_file, open_mode) @@ -907,6 +917,7 @@ def call_timeout(command, timeout): ################################## + def is_available(what, func): # type: (str, Callable[[], bool]) -> None """ @@ -916,12 +927,12 @@ def is_available(what, func): :param func: the callable object that determines availability """ retry = args.retry - logger.info('Waiting for %s...' % (what)) + logger.info('Waiting for %s...' % what) num = 1 while True: if func(): logger.info('%s is available' - % (what)) + % what) break elif num > retry: raise Error('%s not available after %s tries' @@ -956,11 +967,13 @@ def read_config(fn): return cp + def pathify(p): # type: (str) -> str p = os.path.expanduser(p) return os.path.abspath(p) + def get_file_timestamp(fn): # type: (str) -> Optional[str] try: @@ -971,6 +984,7 @@ def get_file_timestamp(fn): except Exception as e: return None + def try_convert_datetime(s): # type: (str) -> Optional[str] # This is super irritating because @@ -1011,6 +1025,7 @@ def try_convert_datetime(s): pass return None + def get_podman_version(): # type: () -> Tuple[int, ...] if 'podman' not in container_path: @@ -1018,6 +1033,7 @@ def get_podman_version(): out, _, _ = call_throws([container_path, '--version']) return _parse_podman_version(out) + def _parse_podman_version(out): # type: (str) -> Tuple[int, ...] _, _, version_str = out.strip().split() @@ -1037,24 +1053,29 @@ def get_hostname(): # type: () -> str return socket.gethostname() + def get_fqdn(): # type: () -> str return socket.getfqdn() or socket.gethostname() + def get_arch(): # type: () -> str return platform.uname().machine + def generate_service_id(): # type: () -> str return get_hostname() + '.' + ''.join(random.choice(string.ascii_lowercase) for _ in range(6)) + def generate_password(): # type: () -> str return ''.join(random.choice(string.ascii_lowercase + string.digits) for i in range(10)) + def normalize_container_id(i): # type: (str) -> str # docker adds the sha256: prefix, but AFAICS both @@ -1066,10 +1087,12 @@ def normalize_container_id(i): i = i[len(prefix):] return i + def make_fsid(): # type: () -> str return str(uuid.uuid1()) + def is_fsid(s): # type: (str) -> bool try: @@ -1078,6 +1101,7 @@ def is_fsid(s): return False return True + def infer_fsid(func): """ If we only find a single fsid in /var/lib/ceph/*, use that @@ -1114,6 +1138,7 @@ def infer_fsid(func): return _infer_fsid + def infer_config(func): """ If we find a MON daemon, use the config from that container @@ -1144,6 +1169,7 @@ def infer_config(func): return _infer_config + def _get_default_image(): if DEFAULT_IMAGE_IS_MASTER: warn = '''This is a development version of cephadm. @@ -1154,6 +1180,7 @@ For information regarding the latest stable release: logger.warning('{}{}{}'.format(termcolor.yellow, line, termcolor.end)) return DEFAULT_IMAGE + def infer_image(func): """ Use the most recent ceph image @@ -1170,6 +1197,7 @@ def infer_image(func): return _infer_image + def default_image(func): @wraps(func) def _default_image(): @@ -1187,6 +1215,7 @@ def default_image(func): return _default_image + def get_last_local_ceph_image(): """ :return: The most recent local ceph image (already pulled) @@ -1203,6 +1232,7 @@ def get_last_local_ceph_image(): return r return None + def write_tmp(s, uid, gid): # type: (str, int, int) -> Any tmp_f = tempfile.NamedTemporaryFile(mode='w', @@ -1213,6 +1243,7 @@ def write_tmp(s, uid, gid): return tmp_f + def makedirs(dir, uid, gid, mode): # type: (str, int, int, int) -> None if not os.path.exists(dir): @@ -1222,14 +1253,17 @@ 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): # type: (str, str, Union[int, str]) -> str return os.path.join(args.data_dir, fsid, '%s.%s' % (t, n)) + def get_log_dir(fsid): # type: (str) -> str return os.path.join(args.log_dir, fsid) + def make_data_dir_base(fsid, uid, gid): # type: (str, int, int) -> str data_dir_base = os.path.join(args.data_dir, fsid) @@ -1239,6 +1273,7 @@ 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): # type: (str, str, Union[int, str], int, int) -> str if not uid or not gid: @@ -1248,6 +1283,7 @@ def make_data_dir(fsid, daemon_type, daemon_id, uid=None, gid=None): makedirs(data_dir, uid, gid, DATA_DIR_MODE) return data_dir + def make_log_dir(fsid, uid=None, gid=None): # type: (str, int, int) -> str if not uid or not gid: @@ -1256,11 +1292,13 @@ def make_log_dir(fsid, uid=None, gid=None): makedirs(log_dir, uid, gid, LOG_DIR_MODE) return log_dir + def make_var_run(fsid, uid, gid): # type: (str, int, int) -> None call_throws(['install', '-d', '-m0770', '-o', str(uid), '-g', str(gid), '/var/run/ceph/%s' % fsid]) + def copy_tree(src, dst, uid=None, gid=None): # type: (List[str], str, int, int) -> None """ @@ -1305,6 +1343,7 @@ def copy_files(src, dst, uid=None, gid=None): logger.debug('chown %s:%s \'%s\'' % (uid, gid, dst_file)) os.chown(dst_file, uid, gid) + def move_files(src, dst, uid=None, gid=None): # type: (List[str], str, int, int) -> None """ @@ -1330,6 +1369,7 @@ def move_files(src, dst, uid=None, gid=None): logger.debug('chown %s:%s \'%s\'' % (uid, gid, dst_file)) os.chown(dst_file, uid, gid) + ## copied from distutils ## def find_executable(executable, path=None): """Tries to find 'executable' in the directories listed in 'path'. @@ -1366,6 +1406,7 @@ def find_executable(executable, path=None): return f return None + def find_program(filename): # type: (str) -> str name = find_executable(filename) @@ -1373,6 +1414,7 @@ def find_program(filename): raise ValueError('%s not found' % filename) return name + def get_unit_name(fsid, daemon_type, daemon_id=None): # type: (str, str, Optional[Union[int, str]]) -> str # accept either name or type + id @@ -1381,6 +1423,7 @@ def get_unit_name(fsid, daemon_type, daemon_id=None): else: return 'ceph-%s@%s' % (fsid, daemon_type) + def get_unit_name_by_daemon_name(fsid, name): daemon = get_daemon_description(fsid, name) try: @@ -1388,6 +1431,7 @@ def get_unit_name_by_daemon_name(fsid, name): except KeyError: raise Error('Failed to get unit name for {}'.format(daemon)) + def check_unit(unit_name): # type: (str) -> Tuple[bool, str, bool] # NOTE: we ignore the exit code here because systemctl outputs @@ -1426,6 +1470,7 @@ def check_unit(unit_name): state = 'unknown' return (enabled, state, installed) + def check_units(units, enabler=None): # type: (List[str], Optional[Packager]) -> bool for u in units: @@ -1439,6 +1484,7 @@ def check_units(units, enabler=None): enabler.enable_service(u) return False + def get_legacy_config_fsid(cluster, legacy_dir=None): # type: (str, str) -> Optional[str] config_file = '/etc/ceph/%s.conf' % cluster @@ -1451,6 +1497,7 @@ def get_legacy_config_fsid(cluster, legacy_dir=None): return config.get('global', 'fsid') return None + def get_legacy_daemon_fsid(cluster, daemon_type, daemon_id, legacy_dir=None): # type: (str, str, Union[int, str], str) -> Optional[str] fsid = None @@ -1470,6 +1517,7 @@ def get_legacy_daemon_fsid(cluster, daemon_type, daemon_id, legacy_dir=None): fsid = get_legacy_config_fsid(cluster, legacy_dir=legacy_dir) return fsid + def get_daemon_args(fsid, daemon_type, daemon_id): # type: (str, str, Union[int, str]) -> List[str] r = list() # type: List[str] @@ -1501,6 +1549,7 @@ def get_daemon_args(fsid, daemon_type, daemon_id): return r + def create_daemon_dirs(fsid, daemon_type, daemon_id, uid, gid, config=None, keyring=None): # type: (str, str, Union[int, str], int, int, Optional[str], Optional[str]) -> None @@ -1545,7 +1594,6 @@ def create_daemon_dirs(fsid, daemon_type, daemon_id, uid, gid, makedirs(os.path.join(data_dir_root, config_dir), uid, gid, 0o755) makedirs(os.path.join(data_dir_root, config_dir, 'data'), uid, gid, 0o755) - # populate the config directory for the component from the config-json for fname in required_files: if 'files' in config: # type: ignore @@ -1567,6 +1615,7 @@ def create_daemon_dirs(fsid, daemon_type, daemon_id, uid, gid, ceph_iscsi = CephIscsi.init(fsid, daemon_id) ceph_iscsi.create_daemon_dirs(data_dir, uid, gid) + def get_parm(option): # type: (str) -> Dict[str, str] @@ -1601,6 +1650,7 @@ def get_parm(option): else: return js + def get_config_and_keyring(): # type: () -> Tuple[Optional[str], Optional[str]] config = None @@ -1621,7 +1671,8 @@ def get_config_and_keyring(): with open(args.keyring, 'r') as f: keyring = f.read() - return (config, keyring) + return config, keyring + def get_container_binds(fsid, daemon_type, daemon_id): # type: (str, str, Union[int, str, None]) -> List[List[str]] @@ -1633,6 +1684,7 @@ def get_container_binds(fsid, daemon_type, daemon_id): return binds + def get_container_mounts(fsid, daemon_type, daemon_id, no_config=False): # type: (str, str, Union[int, str, None], Optional[bool]) -> Dict[str, str] @@ -1716,6 +1768,7 @@ def get_container_mounts(fsid, daemon_type, daemon_id, return mounts + def get_container(fsid, daemon_type, daemon_id, privileged=False, ptrace=False, @@ -1752,7 +1805,7 @@ def get_container(fsid, daemon_type, daemon_id, entrypoint = '' name = '' - ceph_args = [] # type: List[str] + ceph_args = [] # type: List[str] if daemon_type in Monitoring.components: uid, gid = extract_uid_gid_monitoring(daemon_type) m = Monitoring.components[daemon_type] # type: ignore @@ -1773,7 +1826,7 @@ def get_container(fsid, daemon_type, daemon_id, elif daemon_type in Ceph.daemons: ceph_args = ['-n', name, '-f'] - envs=[] # type: List[str] + envs = [] # type: List[str] if daemon_type == NFSGanesha.daemon_type: envs.extend(NFSGanesha.get_container_envs()) @@ -1790,6 +1843,7 @@ def get_container(fsid, daemon_type, daemon_id, ptrace=ptrace, ) + def extract_uid_gid(img='', file_path='/var/lib/ceph'): # type: (str, str) -> Tuple[int, int] @@ -1802,7 +1856,8 @@ def extract_uid_gid(img='', file_path='/var/lib/ceph'): args=['-c', '%u %g', file_path] ).run() (uid, gid) = out.split(' ') - return (int(uid), int(gid)) + return int(uid), int(gid) + def deploy_daemon(fsid, daemon_type, daemon_id, c, uid, gid, config=None, keyring=None, @@ -1879,6 +1934,7 @@ def deploy_daemon(fsid, daemon_type, daemon_id, c, uid, gid, call_throws(['systemctl', 'restart', get_unit_name(fsid, daemon_type, daemon_id)]) + def deploy_daemon_units(fsid, uid, gid, daemon_type, daemon_id, c, enable=True, start=True, osd_fsid=None): @@ -1989,6 +2045,7 @@ def deploy_daemon_units(fsid, uid, gid, daemon_type, daemon_id, c, if start: call_throws(['systemctl', 'start', unit_name]) + def update_firewalld(daemon_type): # type: (str) -> None if args.skip_firewalld: @@ -2040,6 +2097,7 @@ def update_firewalld(daemon_type): logger.debug('firewalld port %s is enabled in current zone' % tcp_port) call_throws([cmd, '--reload']) + def install_base_units(fsid): # type: (str) -> None """ @@ -2108,6 +2166,7 @@ def install_base_units(fsid): } """ % fsid) + def get_unit_file(fsid): # type: (str) -> str u = """# generated by cephadm @@ -2150,6 +2209,7 @@ WantedBy=ceph-{fsid}.target ################################## + class CephContainer: def __init__(self, image, @@ -2176,15 +2236,15 @@ class CephContainer: def run_cmd(self): # type: () -> List[str] - vols = [] # type: List[str] - envs = [] # type: List[str] - cname = [] # type: List[str] - binds = [] # type: List[str] - entrypoint = [] # type: List[str] + vols = [] # type: List[str] + envs = [] # type: List[str] + cname = [] # type: List[str] + binds = [] # type: List[str] + entrypoint = [] # type: List[str] if self.entrypoint: entrypoint = ['--entrypoint', self.entrypoint] - priv = [] # type: List[str] + priv = [] # type: List[str] if self.privileged: priv = ['--privileged', # let OSD etc read block devs that haven't been chowned @@ -2219,12 +2279,12 @@ class CephContainer: def shell_cmd(self, cmd): # type: (List[str]) -> List[str] - priv = [] # type: List[str] + priv = [] # type: List[str] if self.privileged: priv = ['--privileged', # let OSD etc read block devs that haven't been chowned '--group-add=disk'] - vols = [] # type: List[str] + vols = [] # type: List[str] vols = sum( [['-v', '%s:%s' % (host_dir, container_dir)] for host_dir, container_dir in self.volume_mounts.items()], []) @@ -2281,6 +2341,7 @@ class CephContainer: ################################## + @infer_image def command_version(): # type: () -> int @@ -2290,6 +2351,7 @@ def command_version(): ################################## + @infer_image def command_pull(): # type: () -> int @@ -2299,6 +2361,7 @@ def command_pull(): ################################## + @infer_image def command_inspect_image(): # type: () -> int @@ -2319,6 +2382,7 @@ def command_inspect_image(): ################################## + def is_ipv6(address): # type: (str) -> bool if address.startswith('[') and address.endswith(']'): @@ -2825,6 +2889,7 @@ def command_bootstrap(): ################################## + def extract_uid_gid_monitoring(daemon_type): # type: (str) -> Tuple[int, int] @@ -2925,6 +2990,7 @@ def command_deploy(): ################################## + @infer_image def command_run(): # type: () -> int @@ -2935,6 +3001,7 @@ def command_run(): ################################## + @infer_fsid @infer_config @infer_image @@ -3009,6 +3076,7 @@ def command_shell(): ################################## + @infer_fsid def command_enter(): # type: () -> int @@ -3036,6 +3104,7 @@ def command_enter(): ################################## + @infer_fsid @infer_image def command_ceph_volume(): @@ -3078,6 +3147,7 @@ def command_ceph_volume(): ################################## + @infer_fsid def command_unit(): # type: () -> None @@ -3093,6 +3163,7 @@ def command_unit(): ################################## + @infer_fsid def command_logs(): # type: () -> None @@ -3113,6 +3184,7 @@ def command_logs(): ################################## + def list_networks(): # type: () -> Dict[str,List[str]] @@ -3126,10 +3198,12 @@ def list_networks(): res.update(_list_ipv6_networks()) return res + def _list_ipv4_networks(): out, _, _ = call_throws([find_executable('ip'), 'route', 'ls']) return _parse_ipv4_route(out) + def _parse_ipv4_route(out): r = {} # type: Dict[str,List[str]] p = re.compile(r'^(\S+) (.*)scope link (.*)src (\S+)') @@ -3144,11 +3218,13 @@ def _parse_ipv4_route(out): r[net].append(ip) return r + def _list_ipv6_networks(): routes, _, _ = call_throws([find_executable('ip'), '-6', 'route', 'ls']) ips, _, _ = call_throws([find_executable('ip'), '-6', 'addr', 'ls']) return _parse_ipv6_route(routes, ips) + def _parse_ipv6_route(routes, ips): r = {} # type: Dict[str,List[str]] route_p = re.compile(r'^(\S+) dev (\S+) proto (\S+) metric (\S+) pref (\S+)$') @@ -3174,6 +3250,7 @@ def _parse_ipv6_route(routes, ips): return r + def command_list_networks(): # type: () -> None r = list_networks() @@ -3181,12 +3258,14 @@ def command_list_networks(): ################################## + def command_ls(): # type: () -> None ls = list_daemons(detail=not args.no_detail, legacy_dir=args.legacy_dir) print(json.dumps(ls, indent=4)) + def list_daemons(detail=True, legacy_dir=None): # type: (bool, Optional[str]) -> List[Dict[str, str]] host_version = None @@ -3615,6 +3694,7 @@ def command_adopt_prometheus(daemon_id, fsid): deploy_daemon(fsid, daemon_type, daemon_id, c, uid, gid) update_firewalld(daemon_type) + def command_adopt_grafana(daemon_id, fsid): # type: (str, str) -> None @@ -3657,7 +3737,6 @@ def command_adopt_grafana(daemon_id, fsid): else: logger.debug("Skipping ssl, missing cert {} or key {}".format(cert, key)) - # data - possible custom dashboards/plugins data_src = '/var/lib/grafana/' data_src = os.path.abspath(args.legacy_dir + data_src) @@ -3669,6 +3748,7 @@ def command_adopt_grafana(daemon_id, fsid): deploy_daemon(fsid, daemon_type, daemon_id, c, uid, gid) update_firewalld(daemon_type) + def command_adopt_alertmanager(daemon_id, fsid): # type: (str, str) -> None @@ -3698,6 +3778,7 @@ def command_adopt_alertmanager(daemon_id, fsid): deploy_daemon(fsid, daemon_type, daemon_id, c, uid, gid) update_firewalld(daemon_type) + def _adjust_grafana_ini(filename): # type: (str) -> None @@ -3773,6 +3854,7 @@ def command_rm_daemon(): ################################## + def command_rm_cluster(): # type: () -> None if not args.force: @@ -3856,6 +3938,7 @@ def check_time_sync(enabler=None): return False return True + def command_check_host(): # type: () -> None errors = [] @@ -3900,6 +3983,7 @@ def command_check_host(): ################################## + def command_prepare_host(): # type: () -> None logger.info('Verifying podman|docker is present...') @@ -3935,6 +4019,7 @@ def command_prepare_host(): ################################## + class CustomValidation(argparse.Action): def _check_name(self, values): @@ -3957,6 +4042,7 @@ class CustomValidation(argparse.Action): ################################## + def get_distro(): # type: () -> Tuple[Optional[str], Optional[str], Optional[str]] distro = None @@ -3978,6 +4064,7 @@ def get_distro(): distro_codename = val.lower() return distro, distro_version, distro_codename + class Packager(object): def __init__(self, stable=None, version=None, branch=None, commit=None): assert \ @@ -4105,6 +4192,7 @@ class Apt(Packager): logging.info('Podman did not work. Falling back to docker...') self.install(['docker.io']) + class YumDnf(Packager): DISTRO_NAMES = { 'centos': ('centos', 'el'), @@ -4370,16 +4458,19 @@ def command_add_repo(): commit=args.dev_commit) pkg.add_repo() + def command_rm_repo(): pkg = create_packager() pkg.rm_repo() + def command_install(): pkg = create_packager() pkg.install(args.packages) ################################## + def _get_parser(): # type: () -> argparse.ArgumentParser parser = argparse.ArgumentParser( @@ -4850,6 +4941,7 @@ def _get_parser(): return parser + def _parse_args(av): parser = _get_parser() args = parser.parse_args(av) @@ -4857,10 +4949,11 @@ def _parse_args(av): args.command.pop(0) return args + if __name__ == "__main__": # allow argv to be injected try: - av = injected_argv # type: ignore + av = injected_argv # type: ignore except NameError: av = sys.argv[1:] args = _parse_args(av) -- 2.39.5