From 70e18d99b8e3e77bb37e218d7ac582130156f8ef Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Thu, 25 Jan 2024 09:46:18 +0100 Subject: New upstream version 1.45.90 --- tools/generate-docs-nm-property-infos.py | 133 +++++++++++++++++++++++--- tools/generate-docs-nm-settings-docs-gir.py | 41 +++++--- tools/generate-docs-nm-settings-docs-merge.py | 4 +- tools/run-nm-test.sh | 8 +- tools/test-cloud-meta-mock.py | 2 - tools/test-networkmanager-service.py | 17 +--- 6 files changed, 158 insertions(+), 47 deletions(-) (limited to 'tools') diff --git a/tools/generate-docs-nm-property-infos.py b/tools/generate-docs-nm-property-infos.py index d7e3c8c2..74dc9d1c 100755 --- a/tools/generate-docs-nm-property-infos.py +++ b/tools/generate-docs-nm-property-infos.py @@ -14,6 +14,9 @@ class LineError(Exception): self.line_no = line_no +enums = {} +enumvals = {} + _dbg_level = 0 try: _dbg_level = int(os.getenv("NM_DEBUG_GENERATE_DOCS", 0)) @@ -52,6 +55,45 @@ def xnode_get_or_create(root_node, node_name, name): return node, created +def init_enumvals(girxml): + ns_map = { + "c": "http://www.gtk.org/introspection/c/1.0", + "gi": "http://www.gtk.org/introspection/core/1.0", + "glib": "http://www.gtk.org/introspection/glib/1.0", + } + type_key = "{%s}type" % ns_map["c"] + identifier_key = "{%s}identifier" % ns_map["c"] + nick_key = "{%s}nick" % ns_map["glib"] + + for enum in girxml.findall("./gi:namespace/gi:enumeration", ns_map): + enum_cname = enum.attrib[type_key] + enums[enum_cname] = [] + for enumval in enum.findall("./gi:member", ns_map): + cname = enumval.attrib[identifier_key] + doc = enumval.find("./gi:doc", ns_map) + + enums[enum_cname].append(cname) + enumvals[cname] = { + "value": enumval.attrib["value"], + "nick": enumval.attrib.get(nick_key, cname), + "doc": doc.text if doc is not None else None, + } + + for enum in girxml.findall("./gi:namespace/gi:bitfield", ns_map): + enum_cname = enum.attrib[type_key] + enums[enum_cname] = [] + for enumval in enum.findall("./gi:member", ns_map): + cname = enumval.attrib[identifier_key] + doc = enumval.find("./gi:doc", ns_map) + + enums[enum_cname].append(cname) + enumvals[cname] = { + "value": "0x%x" % int(enumval.attrib["value"]), + "nick": enumval.attrib.get(nick_key, cname), + "doc": doc.text if doc is not None else None, + } + + def get_setting_names(source_file): m = re.match(r"^(.*)/libnm-core-impl/(nm-setting-[^/]*)\.c$", source_file) assert m @@ -125,6 +167,7 @@ keywords = collections.OrderedDict( ("variable", KEYWORD_XML_TYPE_ATTR), ("format", KEYWORD_XML_TYPE_ATTR), ("values", KEYWORD_XML_TYPE_ATTR), + ("special-values", KEYWORD_XML_TYPE_ATTR), ("default", KEYWORD_XML_TYPE_ATTR), ("example", KEYWORD_XML_TYPE_ATTR), ("description", KEYWORD_XML_TYPE_ELEM), @@ -141,7 +184,6 @@ def keywords_allowed(tag, keyword): def write_data(tag, setting_node, line_no, parsed_data): - for k in parsed_data.keys(): assert keywords_allowed(tag, k) assert k in keywords @@ -171,15 +213,50 @@ def write_data(tag, setting_node, line_no, parsed_data): else: assert False + +def expand_enumval(enumval_name, nick_first): + if enumval_name not in enumvals: + return enumval_name + + enumval = enumvals[enumval_name] + if nick_first: + return "%s (%s)" % (enumval["nick"], enumval["value"]) + else: + return "%s (%s)" % (enumval["value"], enumval["nick"]) + + +def expand_all_enumvals(enum, nick_first): + assert enum in enums, "Enum name not found: %s" % enum + return ", ".join(expand_enumval(val_name, nick_first) for val_name in enums[enum]) + + +def expand_all_enumvals_with_docs(enum, nick_first): + assert enum in enums, "Enum name not found: %s" % enum + + out_str = "" + for enumval_name in enums[enum]: + assert enumval_name in enumvals + enumval = enumvals[enumval_name] + out_str += "%s%s" % ( + expand_enumval(enumval_name, nick_first), + " - " + enumval["doc"] if enumval["doc"] else "", + ) + out_str += "" + + return out_str + + +def format_descriptions(tag, parsed_data): if ( parsed_data.get("description", None) is not None and parsed_data.get("description-docbook", None) is None ): # we have a description, but no docbook. Generate one. - node = ET.SubElement(property_node, "description-docbook") - for l in re.split("\n", parsed_data["description"]): - paragraph = ET.SubElement(node, "para") - paragraph.text = l + parsed_data["description-docbook"] = "" + for line in parsed_data["description"].split("\n"): + para = ET.Element("para") + para.text = line + parsed_data["description-docbook"] += ET.tostring(para, encoding="unicode") elif ( parsed_data.get("description-docbook", None) is not None and parsed_data.get("description", None) is None @@ -187,10 +264,35 @@ def write_data(tag, setting_node, line_no, parsed_data): raise Exception( 'Invalid configuration. When specifying "description-docbook:" there MUST be also a "description:"' ) + elif parsed_data.get("description", None) is None: + return + + # Expand enumvals expressions (%ENUM_VALUE and #EnumName:*) + nick_first = tag == "nmcli" + + parsed_data["description"] = re.sub( + r"#([A-Za-z0-9_]*):\*", + lambda match: expand_all_enumvals(match.group(1), nick_first), + parsed_data["description"], + ) + + parsed_data["description"] = re.sub( + r"%([^%]\w*)", + lambda match: expand_enumval(match.group(1), nick_first), + parsed_data["description"], + ) + parsed_data["description-docbook"] = re.sub( + r"#([A-Za-z0-9_]*):\*", + lambda match: expand_all_enumvals_with_docs(match.group(1), nick_first), + parsed_data["description-docbook"], + ) -kwd_first_line_re = re.compile(r"^ *\* ([-a-z0-9]+): (.*)$") -kwd_more_line_re = re.compile(r"^ *\*( *)(.*?)\s*$") + parsed_data["description-docbook"] = re.sub( + r"%([^%]\w*)", + lambda match: expand_enumval(match.group(1), nick_first), + parsed_data["description-docbook"], + ) def parse_data(tag, line_no, lines): @@ -272,7 +374,6 @@ def parse_data(tag, line_no, lines): def process_setting(tag, root_node, source_file, setting_name): - dbg( "> > tag:%s, source_file:%s, setting_name:%s" % (tag, source_file, setting_name) ) @@ -325,6 +426,7 @@ def process_setting(tag, root_node, source_file, setting_name): parsed_data = parse_data(tag, line_no_start, lines) if not parsed_data: raise Exception('invalid data: line %s, "%s"' % (line_no, lines)) + format_descriptions(tag, parsed_data) dbg("> > > property: %s" % (parsed_data["property"],)) if _dbg_level > 1: for keyword in sorted(parsed_data.keys()): @@ -343,12 +445,13 @@ def process_setting(tag, root_node, source_file, setting_name): raise LineError(line_no_start, "Unterminated start tag") -def process_settings_docs(tag, output, source_files): - +def process_settings_docs(tag, output, gir_file, source_files): dbg("> tag:%s, output:%s" % (tag, output)) root_node = ET.Element("nm-setting-docs") + init_enumvals(ET.parse(gir_file).getroot()) + for setting_name, source_file in get_file_infos(source_files): try: process_setting(tag, root_node, source_file, setting_name) @@ -368,11 +471,16 @@ def process_settings_docs(tag, output, source_files): def main(): if len(sys.argv) < 4: - print("Usage: %s [tag] [output-xml-file] [srcfiles...]" % (sys.argv[0])) + print( + "Usage: %s [tag] [output-xml-file] [gir-file] [srcfiles...]" % (sys.argv[0]) + ) exit(1) process_settings_docs( - tag=sys.argv[1], output=sys.argv[2], source_files=sys.argv[3:] + tag=sys.argv[1], + output=sys.argv[2], + gir_file=sys.argv[3], + source_files=sys.argv[4:], ) @@ -420,7 +528,6 @@ def test_get_setting_names(): def test_get_file_infos(): - t = ["connection", "ip-config", "ip4-config", "proxy", "wired"] assert [ diff --git a/tools/generate-docs-nm-settings-docs-gir.py b/tools/generate-docs-nm-settings-docs-gir.py index b8f29d3b..e438d87a 100755 --- a/tools/generate-docs-nm-settings-docs-gir.py +++ b/tools/generate-docs-nm-settings-docs-gir.py @@ -57,6 +57,7 @@ ns_map = { identifier_key = "{%s}identifier" % ns_map["c"] nick_key = "{%s}nick" % ns_map["glib"] symbol_prefix_key = "{%s}symbol-prefix" % ns_map["c"] +nick_key = "{%s}nick" % ns_map["glib"] constants = { "TRUE": "TRUE", @@ -74,25 +75,37 @@ def get_setting_name_define(setting): raise Exception('Unexpected symbol_prefix_key "%s"' % (n)) -def init_constants(girxml, settings): +def init_constants(girxml, settings, output_target): for const in girxml.findall("./gi:namespace/gi:constant", ns_map): cname = const.attrib["{%s}type" % ns_map["c"]] - cvalue = const.attrib["value"] + value = const.attrib["value"] if const.find('./gi:type[@name="utf8"]', ns_map) is not None: - cvalue = '"%s"' % cvalue - constants[cname] = cvalue + value = '"%s"' % value + constants[cname] = value for enum in girxml.findall("./gi:namespace/gi:enumeration", ns_map): for enumval in enum.findall("./gi:member", ns_map): cname = enumval.attrib[identifier_key] - cvalue = "%s (%s)" % (cname, enumval.attrib["value"]) - constants[cname] = cvalue + nick = enumval.attrib.get(nick_key, cname) + if output_target == "nmcli": + value = '"%s" (%s)' % (nick, enumval.attrib["value"]) + elif output_target is not None: + value = "%s (%s)" % (enumval.attrib["value"], nick) + else: + value = "%s (%s)" % (cname, enumval.attrib["value"]) + constants[cname] = value for enum in girxml.findall("./gi:namespace/gi:bitfield", ns_map): for enumval in enum.findall("./gi:member", ns_map): cname = enumval.attrib[identifier_key] - cvalue = "%s (0x%x)" % (cname, int(enumval.attrib["value"])) - constants[cname] = cvalue + nick = enumval.attrib.get(nick_key, cname) + if output_target == "nmcli": + value = '"%s" (0x%x)' % (nick, int(enumval.attrib["value"])) + elif output_target is not None: + value = "0x%x (%s)" % (int(enumval.attrib["value"]), nick) + else: + value = "%s (0x%x)" % (cname, int(enumval.attrib["value"])) + constants[cname] = value for setting in settings: setting_type_name = "NM" + setting.attrib["name"] @@ -217,7 +230,7 @@ def create_desc_docbook(desc_docbook, description): paragraph.text = l -def main(gir_path_str, output_path_str): +def main(gir_path_str, output_path_str, output_target): girxml = ET.parse(gir_path_str).getroot() basexml = girxml.find('./gi:namespace/gi:class[@name="Setting"]', ns_map) @@ -229,7 +242,7 @@ def main(gir_path_str, output_path_str): ) settings = sorted(settings, key=settings_sort_key) - init_constants(girxml, settings) + init_constants(girxml, settings, output_target) nm_settings_docs_element = ET.Element("nm-setting-docs") docs_gir = ET.ElementTree(nm_settings_docs_element) @@ -362,6 +375,12 @@ if __name__ == "__main__": help="output file", required=True, ) + parser.add_argument( + "-t", + "--target", + choices=["nmcli", "dbus", "keyfile", "ifcfg-rh"], + help="target where the output will be used (i.e. nmcli)", + ) args = parser.parse_args() @@ -369,4 +388,4 @@ if __name__ == "__main__": for lib in args.lib_path: GIRepository.Repository.prepend_library_path(lib) - main(args.gir, args.output) + main(args.gir, args.output, args.target) diff --git a/tools/generate-docs-nm-settings-docs-merge.py b/tools/generate-docs-nm-settings-docs-merge.py index a927400f..3ad8755d 100755 --- a/tools/generate-docs-nm-settings-docs-merge.py +++ b/tools/generate-docs-nm-settings-docs-merge.py @@ -250,7 +250,6 @@ settings_roots = [node_to_dict(root, "setting", "name") for root in xml_roots] root_node = ET.Element("nm-setting-docs") for setting_name in iter_keys_of_dicts(settings_roots, key_fcn_setting_name): - dbg("> > setting_name: %s" % (setting_name)) if skip_property(setting_name, None): @@ -272,7 +271,6 @@ for setting_name in iter_keys_of_dicts(settings_roots, key_fcn_setting_name): dbg("> > > create node") for property_name in iter_keys_of_dicts(properties): - dbg("> > > > property_name: %s" % (property_name)) properties_attrs = [p.get(property_name) for p in properties] @@ -296,6 +294,8 @@ for setting_name in iter_keys_of_dicts(settings_roots, key_fcn_setting_name): else: node_set_attr(property_node, "type", properties_attrs) + node_set_attr(property_node, "values", properties_attrs) + node_set_attr(property_node, "special-values", properties_attrs) node_set_attr(property_node, "default", properties_attrs) node_set_attr(property_node, "alias", properties_attrs) diff --git a/tools/run-nm-test.sh b/tools/run-nm-test.sh index c88a1bd5..264fc48d 100755 --- a/tools/run-nm-test.sh +++ b/tools/run-nm-test.sh @@ -135,12 +135,12 @@ else NMTST_USE_VALGRIND=0 fi - if [ -z "${NMTST_LIBTOOL+x}" ]; then + if [ -n "$NMTST_LIBTOOL" ] ; then + NMTST_LIBTOOL=("$NMTST_LIBTOOL" "--mode=execute") + elif [ -z "${NMTST_LIBTOOL+x}" -a -f "$SCRIPT_PATH/../libtool" ]; then NMTST_LIBTOOL=(sh "$SCRIPT_PATH/../libtool" "--mode=execute") - elif [ -z "$NMTST_LIBTOOL" ]; then - NMTST_LIBTOOL=() else - NMTST_LIBTOOL=("$NMTST_LIBTOOL" "--mode=execute") + NMTST_LIBTOOL=() fi TEST_ARGV=() unset TEST diff --git a/tools/test-cloud-meta-mock.py b/tools/test-cloud-meta-mock.py index bc0a829e..a396e0da 100755 --- a/tools/test-cloud-meta-mock.py +++ b/tools/test-cloud-meta-mock.py @@ -169,7 +169,6 @@ class SocketHTTPServer(HTTPServer): def create_default_resources_for_provider(provider): - mac1 = b"cc:00:00:00:00:01" mac2 = b"cc:00:00:00:00:02" @@ -244,7 +243,6 @@ def create_default_resources_for_provider(provider): def create_default_resources(): - return {p: create_default_resources_for_provider(p) for p in PROVIDERS} diff --git a/tools/test-networkmanager-service.py b/tools/test-networkmanager-service.py index 9a423123..f274a460 100755 --- a/tools/test-networkmanager-service.py +++ b/tools/test-networkmanager-service.py @@ -50,7 +50,6 @@ class TestError(AssertionError): class Util: - PY3 = sys.version_info[0] == 3 @staticmethod @@ -509,7 +508,6 @@ class BusErr: class NmUtil: @staticmethod def con_hash_to_connection(con_hash, do_verify=False, do_normalize=False): - x_con = [] for v_setting_name, v_setting in list(con_hash.items()): if isinstance(v_setting_name, (dbus.String, str)): @@ -628,7 +626,6 @@ class NmUtil: class ExportedObj(dbus.service.Object): - DBusInterface = collections.namedtuple("DBusInterface", ["dbus_iface", "props"]) @staticmethod @@ -820,12 +817,10 @@ PRP_DEVICE_INTERFACE_FLAGS = "InterfaceFlags" class Device(ExportedObj): - path_counter_next = 1 path_prefix = "/org/freedesktop/NetworkManager/Devices/" def __init__(self, iface, devtype, ident=None): - if ident is None: ident = iface @@ -1210,10 +1205,10 @@ PRP_WIFI_AP_MODE = "Mode" PRP_WIFI_AP_MAX_BITRATE = "MaxBitrate" PRP_WIFI_AP_STRENGTH = "Strength" PRP_WIFI_AP_LAST_SEEN = "LastSeen" +PRP_WIFI_AP_BANDWIDTH = "Bandwidth" class WifiAp(ExportedObj): - path_counter_next = 1 path_prefix = "/org/freedesktop/NetworkManager/AccessPoint/" @@ -1228,7 +1223,6 @@ class WifiAp(ExportedObj): strength=None, ident=None, ): - ExportedObj.__init__(self, ExportedObj.create_path(WifiAp), ident) NM_AP_FLAGS = getattr(NM, "80211ApSecurityFlags") @@ -1268,6 +1262,7 @@ class WifiAp(ExportedObj): PRP_WIFI_AP_MAX_BITRATE: dbus.UInt32(54000), PRP_WIFI_AP_STRENGTH: dbus.Byte(strength), PRP_WIFI_AP_LAST_SEEN: dbus.Int32(NM.utils_get_timestamp_msec() / 1000), + PRP_WIFI_AP_BANDWIDTH: dbus.UInt32(40), } self.dbus_interface_add(IFACE_WIFI_AP, props) @@ -1402,12 +1397,10 @@ PRP_VPN_CONNECTION_BANNER = "Banner" class ActiveConnection(ExportedObj): - path_counter_next = 1 path_prefix = "/org/freedesktop/NetworkManager/ActiveConnection/" def __init__(self, device, con_inst, specific_object): - ExportedObj.__init__(self, ExportedObj.create_path(ActiveConnection)) self.device = device @@ -2034,7 +2027,6 @@ PRP_CONNECTION_FILENAME = "Filename" class Connection(ExportedObj): def __init__(self, path_counter, con_hash, do_verify_strict=True): - path = "/org/freedesktop/NetworkManager/Settings/Connection/%s" % (path_counter) ExportedObj.__init__(self, path) @@ -2077,7 +2069,6 @@ class Connection(ExportedObj): return self.get_type() == NM.SETTING_VPN_SETTING_NAME def update_connection(self, con_hash, do_verify_strict): - NmUtil.con_hash_verify(con_hash, do_verify_strict=do_verify_strict) old_uuid = self.get_uuid() @@ -2301,7 +2292,6 @@ PRP_IP4_CONFIG_WINSSERVERS = "WinsServers" class IP4Config(ExportedObj): - path_counter_next = 1 path_prefix = "/org/freedesktop/NetworkManager/IP4Config/" @@ -2500,7 +2490,6 @@ PRP_IP6_CONFIG_DNSPRIORITY = "DnsPriority" class IP6Config(ExportedObj): - path_counter_next = 1 path_prefix = "/org/freedesktop/NetworkManager/IP6Config/" @@ -2674,7 +2663,6 @@ PRP_DHCP4_CONFIG_OPTIONS = "Options" class Dhcp4Config(ExportedObj): - path_counter_next = 1 path_prefix = "/org/freedesktop/NetworkManager/DHCP4Config/" @@ -2715,7 +2703,6 @@ PRP_DHCP6_CONFIG_OPTIONS = "Options" class Dhcp6Config(ExportedObj): - path_counter_next = 1 path_prefix = "/org/freedesktop/NetworkManager/DHCP6Config/" -- cgit 1.3.0-6-gf8a5