1#!/usr/bin/env python3 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright (C) 2018 Intel Corporation 4# All rights reserved. 5# 6 7import sys 8import json 9import argparse 10from collections import OrderedDict 11 12 13def sort_json_object(o): 14 if isinstance(o, dict): 15 sorted_o = OrderedDict() 16 """ Order of keys in JSON object is irrelevant but we need to pick one 17 to be able to compare JSONS. """ 18 for key in sorted(o.keys()): 19 sorted_o[key] = sort_json_object(o[key]) 20 return sorted_o 21 if isinstance(o, list): 22 """ Keep list in the same order but sort each item """ 23 return [sort_json_object(item) for item in o] 24 else: 25 return o 26 27 28def filter_methods(do_remove_global_rpcs): 29 global_rpcs = [ 30 'dsa_scan_accel_module', 31 'iscsi_set_options', 32 'nvmf_set_config', 33 'nvmf_set_max_subsystems', 34 'nvmf_create_transport', 35 'nvmf_set_crdt', 36 'bdev_set_options', 37 'bdev_wait_for_examine', 38 'bdev_iscsi_set_options', 39 'bdev_nvme_set_options', 40 'bdev_nvme_set_hotplug', 41 'sock_impl_set_options', 42 'sock_set_default_impl', 43 'framework_set_scheduler', 44 'accel_crypto_key_create', 45 'accel_assign_opc', 46 'accel_set_options', 47 'dpdk_cryptodev_scan_accel_module', 48 'dpdk_cryptodev_set_driver', 49 'virtio_blk_create_transport', 50 'iobuf_set_options', 51 'bdev_raid_set_options', 52 'fsdev_set_opts', 53 ] 54 55 data = json.loads(sys.stdin.read()) 56 out = {'subsystems': []} 57 for s in data['subsystems']: 58 if s['config']: 59 s_config = [] 60 for config in s['config']: 61 m_name = config['method'] 62 is_global_rpc = m_name in global_rpcs 63 if do_remove_global_rpcs != is_global_rpc: 64 s_config.append(config) 65 else: 66 s_config = None 67 out['subsystems'].append({ 68 'subsystem': s['subsystem'], 69 'config': s_config, 70 }) 71 72 print(json.dumps(out, indent=2)) 73 74 75def check_empty(): 76 data = json.loads(sys.stdin.read()) 77 if not data: 78 raise EOFError("Can't read config!") 79 80 for s in data['subsystems']: 81 if s['config']: 82 print("Config not empty") 83 print(s['config']) 84 sys.exit(1) 85 86 87if __name__ == "__main__": 88 parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) 89 parser.add_argument('-method', dest='method', default=None, 90 help="""One of the methods: 91check_empty 92 check if provided configuration is logically empty 93delete_global_parameters 94 remove pre-init configuration (pre framework_start_init RPC methods) 95delete_configs 96 remove post-init configuration (post framework_start_init RPC methods) 97sort 98 remove nothing - just sort JSON objects (and subobjects but not arrays) 99 in lexicographical order. This can be used to do plain text diff.""") 100 101 args = parser.parse_args() 102 if args.method == "delete_global_parameters": 103 filter_methods(True) 104 elif args.method == "delete_configs": 105 filter_methods(False) 106 elif args.method == "check_empty": 107 check_empty() 108 elif args.method == "sort": 109 """ Wrap input into JSON object so any input is possible here 110 like output from bdev_get_bdevs RPC method""" 111 o = json.loads('{ "the_object": ' + sys.stdin.read() + ' }') 112 print(json.dumps(sort_json_object(o)['the_object'], indent=2)) 113 else: 114 raise ValueError("Invalid method '{}'\n\n{}".format(args.method, parser.format_help())) 115