From 9c5707d107e2c9dd23f3b416a50caaa6d3cf6ebb Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sat, 10 Jan 2026 13:27:15 +0100 Subject: [PATCH] bin: relocate src/show.py to bin/show/ -- all tools in one place - relocate src/show.py to src/bin/show/ - Refactor container() to use run_sysrepo() instead of rolling its own - Replace sysrepocfg with copy which supports nacm - Rename run_sysrepocfg() -> get_json() Signed-off-by: Joachim Wiberg --- configs/aarch32_defconfig | 1 - configs/aarch32_minimal_defconfig | 1 - configs/aarch64_defconfig | 1 - configs/aarch64_minimal_defconfig | 1 - configs/riscv64_defconfig | 1 - configs/x86_64_defconfig | 1 - configs/x86_64_minimal_defconfig | 1 - package/Config.in | 1 - package/bin/bin.mk | 29 ++++- package/show/Config.in | 6 - package/show/show.mk | 19 --- src/{show => bin}/bash_completion.d/show | 0 src/bin/pyproject.toml | 18 +++ src/{show/show.py => bin/show/__init__.py} | 130 +++++++++++---------- src/confd/src/core.c | 2 +- src/klish-plugin-infix/xml/infix.xml | 12 +- src/show/LICENSE | 21 ---- src/show/Makefile | 11 -- 18 files changed, 122 insertions(+), 134 deletions(-) delete mode 100644 package/show/Config.in delete mode 100644 package/show/show.mk rename src/{show => bin}/bash_completion.d/show (100%) create mode 100644 src/bin/pyproject.toml rename src/{show/show.py => bin/show/__init__.py} (83%) delete mode 100644 src/show/LICENSE delete mode 100644 src/show/Makefile diff --git a/configs/aarch32_defconfig b/configs/aarch32_defconfig index a33c38e1..fd084a4e 100644 --- a/configs/aarch32_defconfig +++ b/configs/aarch32_defconfig @@ -141,7 +141,6 @@ BR2_PACKAGE_LOWDOWN=y BR2_PACKAGE_MCD=y BR2_PACKAGE_MDNS_ALIAS=y BR2_PACKAGE_ONIEPROM=y -BR2_PACKAGE_SHOW=y BR2_PACKAGE_ROUSETTE=y BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y IMAGE_ITB_AUX=y diff --git a/configs/aarch32_minimal_defconfig b/configs/aarch32_minimal_defconfig index 9aae459a..99d33e24 100644 --- a/configs/aarch32_minimal_defconfig +++ b/configs/aarch32_minimal_defconfig @@ -141,7 +141,6 @@ BR2_PACKAGE_LOWDOWN=y BR2_PACKAGE_MCD=y BR2_PACKAGE_MDNS_ALIAS=y BR2_PACKAGE_ONIEPROM=y -BR2_PACKAGE_SHOW=y BR2_PACKAGE_ROUSETTE=y BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y IMAGE_ITB_AUX=y diff --git a/configs/aarch64_defconfig b/configs/aarch64_defconfig index da687377..3abb5fd7 100644 --- a/configs/aarch64_defconfig +++ b/configs/aarch64_defconfig @@ -178,7 +178,6 @@ BR2_PACKAGE_PODMAN=y BR2_PACKAGE_PODMAN_DRIVER_BTRFS=y BR2_PACKAGE_PODMAN_DRIVER_DEVICEMAPPER=y BR2_PACKAGE_PODMAN_DRIVER_VFS=y -BR2_PACKAGE_SHOW=y BR2_PACKAGE_TETRIS=y BR2_PACKAGE_ROUSETTE=y BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y diff --git a/configs/aarch64_minimal_defconfig b/configs/aarch64_minimal_defconfig index 34262285..eac6123b 100644 --- a/configs/aarch64_minimal_defconfig +++ b/configs/aarch64_minimal_defconfig @@ -128,7 +128,6 @@ BR2_PACKAGE_CONFD=y BR2_PACKAGE_CONFD_TEST_MODE=y BR2_PACKAGE_GENCERT=y BR2_PACKAGE_STATD=y -BR2_PACKAGE_SHOW=y BR2_PACKAGE_FACTORY=y BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y diff --git a/configs/riscv64_defconfig b/configs/riscv64_defconfig index 30ddff4b..c23e2ee6 100644 --- a/configs/riscv64_defconfig +++ b/configs/riscv64_defconfig @@ -203,7 +203,6 @@ BR2_PACKAGE_PODMAN=y BR2_PACKAGE_PODMAN_DRIVER_BTRFS=y BR2_PACKAGE_PODMAN_DRIVER_DEVICEMAPPER=y BR2_PACKAGE_PODMAN_DRIVER_VFS=y -BR2_PACKAGE_SHOW=y BR2_PACKAGE_TETRIS=y BR2_PACKAGE_ROUSETTE=y BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y diff --git a/configs/x86_64_defconfig b/configs/x86_64_defconfig index ad451694..55a9c3fd 100644 --- a/configs/x86_64_defconfig +++ b/configs/x86_64_defconfig @@ -174,7 +174,6 @@ BR2_PACKAGE_PODMAN=y BR2_PACKAGE_PODMAN_DRIVER_BTRFS=y BR2_PACKAGE_PODMAN_DRIVER_DEVICEMAPPER=y BR2_PACKAGE_PODMAN_DRIVER_VFS=y -BR2_PACKAGE_SHOW=y BR2_PACKAGE_TETRIS=y BR2_PACKAGE_ROUSETTE=y BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y diff --git a/configs/x86_64_minimal_defconfig b/configs/x86_64_minimal_defconfig index 3b9ce6c4..ac8e9a30 100644 --- a/configs/x86_64_minimal_defconfig +++ b/configs/x86_64_minimal_defconfig @@ -143,7 +143,6 @@ BR2_PACKAGE_LOWDOWN=y BR2_PACKAGE_MCD=y BR2_PACKAGE_MDNS_ALIAS=y BR2_PACKAGE_ONIEPROM=y -BR2_PACKAGE_SHOW=y BR2_PACKAGE_ROUSETTE=y BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y IMAGE_ITB_AUX=y diff --git a/package/Config.in b/package/Config.in index bf0dcee4..71cf73cc 100644 --- a/package/Config.in +++ b/package/Config.in @@ -34,7 +34,6 @@ source "$BR2_EXTERNAL_INFIX_PATH/package/podman/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/python-libyang/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/python-yangdoc/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/skeleton-init-finit/Config.in" -source "$BR2_EXTERNAL_INFIX_PATH/package/show/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/tetris/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/libyang-cpp/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/sysrepo-cpp/Config.in" diff --git a/package/bin/bin.mk b/package/bin/bin.mk index 49856cfc..65e7ca1a 100644 --- a/package/bin/bin.mk +++ b/package/bin/bin.mk @@ -10,7 +10,9 @@ BIN_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/bin BIN_LICENSE = BSD-3-Clause BIN_LICENSE_FILES = LICENSE BIN_REDISTRIBUTE = NO -BIN_DEPENDENCIES = sysrepo libite +BIN_DEPENDENCIES = sysrepo libite \ + host-python3 python3 host-python-pypa-build host-python-installer \ + host-python-poetry-core BIN_CONF_OPTS = --disable-silent-rules BIN_AUTORECONF = YES @@ -19,7 +21,30 @@ CFLAGS="$(INFIX_CFLAGS)" endef define BIN_PERMISSIONS - /usr/bin/copy d 04750 root sysrepo - - - - - + /usr/bin/copy d 04750 root klish - - - - - endef +define BIN_BUILD_PYTHON + cd $(BIN_SITE) && \ + $(PKG_PYTHON_PEP517_ENV) $(HOST_DIR)/bin/python3 $(PKG_PYTHON_PEP517_BUILD_CMD) -o $(@D)/dist + mkdir -p $(TARGET_DIR)/usr/bin + rm -f $(TARGET_DIR)/usr/bin/show + cd $(@D) && \ + $(HOST_DIR)/bin/python3 $(TOPDIR)/support/scripts/pyinstaller.py \ + dist/*.whl \ + --interpreter=/usr/bin/python3 \ + --script-kind=posix \ + --purelib=$(TARGET_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR)/site-packages \ + --headers=$(TARGET_DIR)/usr/include/python$(PYTHON3_VERSION_MAJOR) \ + --scripts=$(TARGET_DIR)/usr/bin \ + --data=$(TARGET_DIR) +endef +BIN_POST_INSTALL_TARGET_HOOKS += BIN_BUILD_PYTHON + +define BIN_INSTALL_BASH_COMPLETION + install -D $(@D)/bash_completion.d/show \ + $(TARGET_DIR)/etc/bash_completion.d/show +endef +BIN_POST_INSTALL_TARGET_HOOKS += BIN_INSTALL_BASH_COMPLETION + $(eval $(autotools-package)) diff --git a/package/show/Config.in b/package/show/Config.in deleted file mode 100644 index 2cc1dc23..00000000 --- a/package/show/Config.in +++ /dev/null @@ -1,6 +0,0 @@ -config BR2_PACKAGE_SHOW - bool "show" - help - Tool to retrieve and present operational data from sysrepo. - - https://github.com/kernelkit/infix diff --git a/package/show/show.mk b/package/show/show.mk deleted file mode 100644 index 3db961be..00000000 --- a/package/show/show.mk +++ /dev/null @@ -1,19 +0,0 @@ -################################################################################ -# -# show -# -################################################################################ - -SHOW_VERSION = 1.0 -SHOW_LICENSE = MIT -SHOW_LICENSE_FILES = LICENSE -SHOW_SITE_METHOD = local -SHOW_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/show -SHOW_REDISTRIBUTE = NO - -define SHOW_INSTALL_TARGET_CMDS - $(TARGET_MAKE_ENV) $(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D) \ - DESTDIR="$(TARGET_DIR)" install -endef - -$(eval $(generic-package)) diff --git a/src/show/bash_completion.d/show b/src/bin/bash_completion.d/show similarity index 100% rename from src/show/bash_completion.d/show rename to src/bin/bash_completion.d/show diff --git a/src/bin/pyproject.toml b/src/bin/pyproject.toml new file mode 100644 index 00000000..a8553a70 --- /dev/null +++ b/src/bin/pyproject.toml @@ -0,0 +1,18 @@ +[tool.poetry] +name = "infix-show" +version = "1.0" +description = "Infix show commands" +license = "MIT" +packages = [ + { include = "show" } +] +authors = [ + "KernelKit developers" +] + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry.scripts] +show = "show:main" diff --git a/src/show/show.py b/src/bin/show/__init__.py similarity index 83% rename from src/show/show.py rename to src/bin/show/__init__.py index fccafd70..3c1c79cf 100755 --- a/src/show/show.py +++ b/src/bin/show/__init__.py @@ -10,26 +10,25 @@ import argparse RAW_OUTPUT = False -def run_sysrepocfg(xpath: str, datastore: str = "operational") -> dict: + +def get_json(xpath: str, datastore: str = "operational") -> dict: if not isinstance(xpath, str) or not xpath.startswith("/"): print("Invalid XPATH. It must be a valid string starting with '/'.") return {} - safe_xpath = shlex.quote(xpath) - try: - result = subprocess.run([ - "sysrepocfg", "-f", "json", "-X", "-d", datastore, "-x", safe_xpath - ], capture_output=True, text=True, check=True) + result = subprocess.run(["copy", datastore, "-x", shlex.quote(xpath)], + capture_output=True, text=True, check=True) json_data = json.loads(result.stdout) return json_data except subprocess.CalledProcessError as e: - print(f"Error running sysrepocfg: {e}") + print(f"Error running copy: {e}") return {} except json.JSONDecodeError as e: print(f"Error parsing JSON output: {e}") return {} + def cli_pretty(json_data: dict, command: str, *args: str): if not command or not all(isinstance(arg, str) for arg in args): print("Invalid command or arguments. All arguments must be strings.") @@ -46,8 +45,9 @@ def cli_pretty(json_data: dict, command: str, *args: str): except subprocess.CalledProcessError as e: print(f"Error running cli-pretty: {e}") + def dhcp(args: List[str]) -> None: - data = run_sysrepocfg("/infix-dhcp-server:dhcp-server") + data = get_json("/infix-dhcp-server:dhcp-server") if not data: print("No interface data retrieved.") return @@ -57,8 +57,9 @@ def dhcp(args: List[str]) -> None: return cli_pretty(data, "show-dhcp-server") + def hardware(args: List[str]) -> None: - data = run_sysrepocfg("/ietf-hardware:hardware") + data = get_json("/ietf-hardware:hardware") if not data: print("No hardware data retrieved.") return @@ -68,6 +69,7 @@ def hardware(args: List[str]) -> None: return cli_pretty(data, "show-hardware") + def ntp(args: List[str]) -> None: # Create argument parser for ntp subcommands parser = argparse.ArgumentParser(prog='show ntp', add_help=False) @@ -97,8 +99,8 @@ def ntp(args: List[str]) -> None: # Default: show ntp (no subcommand or address) # Fetch both client and server operational data - client_data = run_sysrepocfg("/system-state/ntp") - server_data = run_sysrepocfg("/ietf-ntp:ntp") + client_data = get_json("/system-state/ntp") + server_data = get_json("/ietf-ntp:ntp") # Merge into single data structure data = {} @@ -121,8 +123,9 @@ def ntp(args: List[str]) -> None: # Default show ntp - summary view (no address support at top level) cli_pretty(data, "show-ntp") + def ntp_tracking(args: List[str]) -> None: - data = run_sysrepocfg("/ietf-ntp:ntp") + data = get_json("/ietf-ntp:ntp") if not data: print("No ntp server data retrieved.") return @@ -132,8 +135,9 @@ def ntp_tracking(args: List[str]) -> None: return cli_pretty(data, "show-ntp-tracking") + def ntp_source(args: List[str]) -> None: - data = run_sysrepocfg("/ietf-ntp:ntp") + data = get_json("/ietf-ntp:ntp") if not data: print("No ntp server data retrieved.") return @@ -148,6 +152,7 @@ def ntp_source(args: List[str]) -> None: else: cli_pretty(data, "show-ntp-source") + def is_valid_interface_name(interface_name: str) -> bool: """ Validates a Linux network interface name. @@ -158,14 +163,15 @@ def is_valid_interface_name(interface_name: str) -> bool: pattern = r'^[a-zA-Z0-9._-]+$' return bool(re.match(pattern, interface_name)) + def interface(args: List[str]) -> None: - data = run_sysrepocfg("/ietf-interfaces:interfaces") + data = get_json("/ietf-interfaces:interfaces") if not data: print("No interface data retrieved.") return # Also fetch routing interface list for forwarding indication - routing_data = run_sysrepocfg("/ietf-routing:routing") + routing_data = get_json("/ietf-routing:routing") if routing_data: # Merge routing data into the main data structure data.update(routing_data) @@ -185,8 +191,9 @@ def interface(args: List[str]) -> None: else: print("Too many arguments provided. Only one interface name is expected.") + def stp(args: List[str]) -> None: - data = run_sysrepocfg("/ietf-interfaces:interfaces") + data = get_json("/ietf-interfaces:interfaces") if not data: print("No interface data retrieved.") return @@ -196,8 +203,9 @@ def stp(args: List[str]) -> None: return cli_pretty(data, "show-bridge-stp") + def software(args: List[str]) -> None: - data = run_sysrepocfg("/ietf-system:system-state/infix-system:software") + data = get_json("/ietf-system:system-state/infix-system:software") if not data: print("No software data retrieved.") return @@ -217,8 +225,9 @@ def software(args: List[str]) -> None: else: print("Too many arguments provided. Only one name is expected.") + def boot_order(args: List[str]) -> None: - data = run_sysrepocfg("/ietf-system:system-state/infix-system:software") + data = get_json("/ietf-system:system-state/infix-system:software") if not data: print("No software data retrieved.") return @@ -230,8 +239,9 @@ def boot_order(args: List[str]) -> None: except (KeyError, TypeError): print("No boot order data available.") + def services(args: List[str]) -> None: - data = run_sysrepocfg("/ietf-system:system-state/infix-system:services") + data = get_json("/ietf-system:system-state/infix-system:services") if not data: print("No service data retrieved.") return @@ -240,7 +250,8 @@ def services(args: List[str]) -> None: print(json.dumps(data, indent=2)) return - cli_pretty(data, f"show-services") + cli_pretty(data, "show-services") + def container(args: List[str]) -> None: """Handle show container [name] @@ -249,44 +260,39 @@ def container(args: List[str]) -> None: (none) - Show all containers in table format name - Show detailed view of specific container """ - data = run_sysrepocfg("/infix-containers:containers") + data = get_json("/infix-containers:containers") if not data: print("No container data retrieved.") return - # Fetch interface data for bridge resolution (both table and detailed views) + # Fetch interface data for bridge resolution (table and detailed views) # Fetch operational interface data - iface_oper = run_sysrepocfg("/ietf-interfaces:interfaces") + iface_oper = get_json("/ietf-interfaces:interfaces") # Also fetch config data for veth peer information (not in operational) - try: - result = subprocess.run([ - "sysrepocfg", "-f", "json", "-X", "-d", "running", "-x", "/ietf-interfaces:interfaces" - ], capture_output=True, text=True, check=True) - iface_config = json.loads(result.stdout) + iface_config = get_json("/ietf-interfaces:interfaces", "running") - # Merge config veth peer info into operational data - if iface_oper and iface_config: - oper_ifaces = iface_oper.get('ietf-interfaces:interfaces', {}).get('interface', []) - config_ifaces = iface_config.get('ietf-interfaces:interfaces', {}).get('interface', []) + # Merge config veth peer info into operational data + if iface_oper and iface_config: + oper_ifaces = iface_oper.get('ietf-interfaces:interfaces', {}).get('interface', []) + config_ifaces = iface_config.get('ietf-interfaces:interfaces', {}).get('interface', []) - # Create a map of config interfaces - config_map = {iface['name']: iface for iface in config_ifaces} + # Create a map of config interfaces + config_map = {iface['name']: iface for iface in config_ifaces} - # Merge veth peer info from config into operational - for oper_iface in oper_ifaces: - name = oper_iface.get('name') - if name in config_map: - config_iface = config_map[name] - # Add veth peer if it exists in config but not in operational - if 'infix-interfaces:veth' in config_iface and 'infix-interfaces:veth' not in oper_iface: - oper_iface['infix-interfaces:veth'] = config_iface['infix-interfaces:veth'] + # Merge veth peer info from config into operational + for oper_iface in oper_ifaces: + name = oper_iface.get('name') + if name in config_map: + config_iface = config_map[name] + # Add veth peer if it exists in config but not in operational + if 'infix-interfaces:veth' in config_iface and 'infix-interfaces:veth' not in oper_iface: + oper_iface['infix-interfaces:veth'] = config_iface['infix-interfaces:veth'] - data.update(iface_oper) - except (subprocess.CalledProcessError, json.JSONDecodeError): + data.update(iface_oper) + elif iface_oper: # If config fetch fails, just use operational data - if iface_oper: - data.update(iface_oper) + data.update(iface_oper) if RAW_OUTPUT: print(json.dumps(data, indent=2)) @@ -300,6 +306,7 @@ def container(args: List[str]) -> None: else: print("Too many arguments provided. Expected: show container [name]") + def bfd(args: List[str]) -> None: """Handle show bfd [subcommand] [peer] [brief] @@ -309,8 +316,7 @@ def bfd(args: List[str]) -> None: peers brief - Show BFD peers in brief format peer - Show specific BFD peer details """ - # Fetch operational data from sysrepocfg - data = run_sysrepocfg("/ietf-routing:routing/control-plane-protocols/control-plane-protocol") + data = get_json("/ietf-routing:routing/control-plane-protocols/control-plane-protocol") if not data: print("No BFD data retrieved.") return @@ -344,7 +350,7 @@ def bfd(args: List[str]) -> None: # For brief view, fetch interface data to show interface:ip format if brief_flag: - ifaces_data = run_sysrepocfg("/ietf-interfaces:interfaces") + ifaces_data = get_json("/ietf-interfaces:interfaces") if ifaces_data: data['_interfaces'] = ifaces_data @@ -361,6 +367,7 @@ def bfd(args: List[str]) -> None: else: print(f"Unknown BFD subcommand: {subcommand}") + def ospf(args: List[str]) -> None: """Handle show ospf [subcommand] [ifname] [detail] @@ -374,8 +381,7 @@ def ospf(args: List[str]) -> None: ifname - Interface name (for interfaces subcommand) detail - Show detailed information (Cisco-style) """ - # Fetch operational data from sysrepocfg - data = run_sysrepocfg("/ietf-routing:routing/control-plane-protocols/control-plane-protocol") + data = get_json("/ietf-routing:routing/control-plane-protocols/control-plane-protocol") if not data: print("No OSPF data retrieved.") return @@ -407,12 +413,12 @@ def ospf(args: List[str]) -> None: data['_ifname'] = ifname # For detailed interface view, fetch additional data (interfaces and BFD) if subcommand == "interface" or subcommand == "interfaces": - ifaces_data = run_sysrepocfg("/ietf-interfaces:interfaces") + ifaces_data = get_json("/ietf-interfaces:interfaces") if ifaces_data: data['_interfaces'] = ifaces_data # Fetch BFD data for per-interface status - routing_data = run_sysrepocfg("/ietf-routing:routing/control-plane-protocols/control-plane-protocol") + routing_data = get_json("/ietf-routing:routing/control-plane-protocols/control-plane-protocol") if routing_data: data['_routing'] = routing_data @@ -428,6 +434,7 @@ def ospf(args: List[str]) -> None: else: print(f"Unknown OSPF subcommand: {subcommand}") + def rip(args: List[str]) -> None: """Handle show rip [subcommand] [ifname] @@ -440,8 +447,7 @@ def rip(args: List[str]) -> None: Optional: ifname - Interface name (for interface subcommand) """ - # Fetch operational data from sysrepocfg - data = run_sysrepocfg("/ietf-routing:routing/control-plane-protocols/control-plane-protocol") + data = get_json("/ietf-routing:routing/control-plane-protocols/control-plane-protocol") if not data: data = {} @@ -469,10 +475,11 @@ def rip(args: List[str]) -> None: else: print(f"Unknown RIP subcommand: {subcommand}") + def routes(args: List[str]): ip_version = args[0] if args and args[0] in ["ipv4", "ipv6"] else "ipv4" - data = run_sysrepocfg("/ietf-routing:routing/ribs") + data = get_json("/ietf-routing:routing/ribs") if not data: print("No route data retrieved.") return @@ -481,8 +488,9 @@ def routes(args: List[str]): return cli_pretty(data, "show-routing-table", "-i", ip_version) + def lldp(args: List[str]): - data = run_sysrepocfg("/ieee802-dot1ab-lldp:lldp") + data = get_json("/ieee802-dot1ab-lldp:lldp") if not data: print("No lldp data retrieved.") return @@ -494,13 +502,13 @@ def lldp(args: List[str]): def system(args: List[str]) -> None: # Get system state from sysrepo - data = run_sysrepocfg("/ietf-system:system-state") + data = get_json("/ietf-system:system-state") if not data: print("No system data retrieved.") return # Get hardware data (including thermal sensors) - hardware_data = run_sysrepocfg("/ietf-hardware:hardware") + hardware_data = get_json("/ietf-hardware:hardware") # Augment with runtime data runtime = {} @@ -596,8 +604,9 @@ def system(args: List[str]) -> None: cli_pretty(data, "show-system") + def nacm(args: List[str]) -> None: - data = run_sysrepocfg("/ietf-netconf-acm:nacm", "running") + data = get_json("/ietf-netconf-acm:nacm", "running") if not data: print("No NACM data retrieved.") return @@ -614,6 +623,7 @@ def nacm(args: List[str]) -> None: return cli_pretty(data, "show-nacm") + def execute_command(command: str, args: List[str]): command_mapping = { 'bfd': bfd, diff --git a/src/confd/src/core.c b/src/confd/src/core.c index fab04e78..b17ed8db 100644 --- a/src/confd/src/core.c +++ b/src/confd/src/core.c @@ -15,7 +15,7 @@ static int startup_save(sr_session_ctx_t *session, uint32_t sub_id, const char * if (systemf("runlevel >/dev/null 2>&1")) return SR_ERR_OK; - if (systemf("sysrepocfg -X/cfg/startup-config.cfg -d startup -f json")) + if (systemf("copy startup /cfg/startup-config.cfg")) return SR_ERR_SYS; return SR_ERR_OK; diff --git a/src/klish-plugin-infix/xml/infix.xml b/src/klish-plugin-infix/xml/infix.xml index 3daf60ed..7fca67fe 100644 --- a/src/klish-plugin-infix/xml/infix.xml +++ b/src/klish-plugin-infix/xml/infix.xml @@ -650,12 +650,12 @@ - sysrepocfg -X -d operational -x /infix-firewall:firewall -f json -t 60 | /usr/libexec/statd/cli-pretty show-firewall-log $KLISH_PARAM_limit |pager +G + copy operational -x /infix-firewall:firewall | /usr/libexec/statd/cli-pretty show-firewall-log $KLISH_PARAM_limit |pager +G - sysrepocfg -X -d operational -x /infix-firewall:firewall -f json -t 60 | /usr/libexec/statd/cli-pretty show-firewall-matrix + copy operational -x /infix-firewall:firewall | /usr/libexec/statd/cli-pretty show-firewall-matrix @@ -663,7 +663,7 @@ - sysrepocfg -X -d operational -x /infix-firewall:firewall -f json -t 60 | /usr/libexec/statd/cli-pretty show-firewall-zone "$KLISH_PARAM_name" |pager + copy operational -x /infix-firewall:firewall | /usr/libexec/statd/cli-pretty show-firewall-zone "$KLISH_PARAM_name" |pager @@ -671,7 +671,7 @@ - sysrepocfg -X -d operational -x /infix-firewall:firewall -f json -t 60 | /usr/libexec/statd/cli-pretty show-firewall-policy "$KLISH_PARAM_name" |pager + copy operational -x /infix-firewall:firewall | /usr/libexec/statd/cli-pretty show-firewall-policy "$KLISH_PARAM_name" |pager @@ -679,12 +679,12 @@ - sysrepocfg -X -d operational -x /infix-firewall:firewall -f json -t 60 | /usr/libexec/statd/cli-pretty show-firewall-service "$KLISH_PARAM_name" |pager + copy operational -x /infix-firewall:firewall | /usr/libexec/statd/cli-pretty show-firewall-service "$KLISH_PARAM_name" |pager - sysrepocfg -X -d operational -x /infix-firewall:firewall -f json -t 60 | /usr/libexec/statd/cli-pretty show-firewall |pager + copy operational -x /infix-firewall:firewall | /usr/libexec/statd/cli-pretty show-firewall |pager diff --git a/src/show/LICENSE b/src/show/LICENSE deleted file mode 100644 index fa7d9811..00000000 --- a/src/show/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2025 Richard Alpe - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/src/show/Makefile b/src/show/Makefile deleted file mode 100644 index 54c31e41..00000000 --- a/src/show/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -.PHONY: all clean distclean install - -all: - -clean: - -distclean: clean - -install: - install -D show.py $(DESTDIR)/bin/show - install -D bash_completion.d/show $(DESTDIR)/etc/bash_completion.d/show