From ff8669e735b7c7a741255bb8ed0aa3663241034f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= Date: Tue, 17 Dec 2024 14:37:57 +0100 Subject: [PATCH 1/4] Add support to set configure with RPC and read it from operational datastore --- src/confd/src/infix-system-software.c | 38 +++++++++- src/confd/yang/infix-system-software.yang | 33 ++++++++- ... => infix-system-software@2024-12-16.yang} | 0 src/klish-plugin-infix/xml/infix.xml | 2 +- src/statd/python/cli_pretty/cli_pretty.py | 17 ++++- src/statd/python/yanger/yanger.py | 70 ++++++++++++++----- test/case/cli/cli-output/show-software.txt | 6 ++ test/case/cli/run.sh | 16 ++++- test/case/cli/system-output/boot-order.txt | 1 + test/case/cli/system-output/rauc-status.json | 2 +- 10 files changed, 159 insertions(+), 26 deletions(-) rename src/confd/yang/{infix-system-software@2023-06-27.yang => infix-system-software@2024-12-16.yang} (100%) create mode 100644 test/case/cli/cli-output/show-software.txt create mode 100644 test/case/cli/system-output/boot-order.txt diff --git a/src/confd/src/infix-system-software.c b/src/confd/src/infix-system-software.c index 355415fe2..1b24a186e 100644 --- a/src/confd/src/infix-system-software.c +++ b/src/confd/src/infix-system-software.c @@ -5,7 +5,6 @@ #include "core.h" #include "rauc-installer.h" - static RaucInstaller *infix_system_sw_new_rauc(void) { RaucInstaller *rauc; @@ -51,12 +50,49 @@ static int infix_system_sw_install(sr_session_ctx_t *session, uint32_t sub_id, return srerr; } +/* + boot order can only be: primary, secondary and net, limited by model + */ +static int infix_system_sw_set_boot_order(sr_session_ctx_t *session, uint32_t sub_id, + const char *path, const sr_val_t *input, + const size_t input_cnt, sr_event_t event, + unsigned request_id, sr_val_t **output, + size_t *output_cnt, void *priv) { + char boot_order[23] = ""; + for (size_t i = 0; i < input_cnt; i++) { + const sr_val_t *val = &input[i]; + + if (i != 0) + strlcat(boot_order, " ", sizeof(boot_order)); + strlcat(boot_order, val->data.string_val, sizeof(boot_order)); + } + + if (fexist("/sys/firmware/devicetree/base/chosen/u-boot,version")) { + if (systemf("fw_setenv BOOT_ORDER %s", boot_order)) { + ERROR("Set-boot-order: Failed to set boot order in U-Boot"); + return SR_ERR_INTERNAL; + } + } else if (fexist("/mnt/aux/grub/grubenv")) { + if (systemf("grub-editenv /mnt/aux/grub/grubenv set ORDER=\"%s\"", boot_order)) { + ERROR("Set-boot-order: Failed to set boot order in Grub"); + return SR_ERR_INTERNAL; + } + } else { + ERROR("No supported boot loader found"); + return SR_ERR_UNSUPPORTED; + } + + return SR_ERR_OK; +} + int infix_system_sw_init(struct confd *confd) { int rc = 0; REGISTER_RPC(confd->session, "/infix-system:install-bundle", infix_system_sw_install, NULL, &confd->sub); + REGISTER_RPC(confd->session, "/infix-system:set-boot-order", + infix_system_sw_set_boot_order, NULL, &confd->sub); fail: return rc; diff --git a/src/confd/yang/infix-system-software.yang b/src/confd/yang/infix-system-software.yang index 2cc449ab8..907b4224d 100644 --- a/src/confd/yang/infix-system-software.yang +++ b/src/confd/yang/infix-system-software.yang @@ -20,6 +20,10 @@ submodule infix-system-software { contact "kernelkit@googlegroups.com"; description "Software status and upgrade."; + revision 2024-12-16 { + description "Add boot-order operational data"; + reference "Internal"; + } revision 2023-06-27 { description "Initial revision."; reference "internal"; @@ -39,6 +43,18 @@ submodule infix-system-software { } } + grouping boot-order { + leaf-list boot-order { + type enumeration { + enum "primary"; + enum "secondary"; + enum "net"; + } + ordered-by user; + min-elements 1; // At least one value is required + max-elements 3; // Ensure reasonable maximum size if needed + } + } grouping installer-state { leaf operation { type string; @@ -64,7 +80,6 @@ submodule infix-system-software { "The last error encountered by the installer service."; } } - augment "/sys:system-state" { container software { description @@ -95,6 +110,7 @@ submodule infix-system-software { description "Slot from which the system was booted."; } + uses boot-order; container installer { description @@ -184,7 +200,7 @@ submodule infix-system-software { } rpc install-bundle { -nacm:default-deny-all; + nacm:default-deny-all; description "Upgrade the system's software by installing the specified bundle."; input { @@ -198,4 +214,17 @@ nacm:default-deny-all; } } } + rpc set-boot-order { + nacm:default-deny-all; + description + "Set order of boot partitions"; + input { + uses boot-order; + must "count(boot-order[.='primary']) <= 1 and + count(boot-order[.='secondary']) <= 1 and + count(boot-order[.='net']) <= 1" { + error-message "Not possible to have duplicate targets in boot order."; + } + } + } } diff --git a/src/confd/yang/infix-system-software@2023-06-27.yang b/src/confd/yang/infix-system-software@2024-12-16.yang similarity index 100% rename from src/confd/yang/infix-system-software@2023-06-27.yang rename to src/confd/yang/infix-system-software@2024-12-16.yang diff --git a/src/klish-plugin-infix/xml/infix.xml b/src/klish-plugin-infix/xml/infix.xml index 23f7cf445..fac72b2cc 100644 --- a/src/klish-plugin-infix/xml/infix.xml +++ b/src/klish-plugin-infix/xml/infix.xml @@ -303,7 +303,7 @@ sysrepocfg -d operational -X -f json -x /ietf-system:system-state/infix-system:software | \ jq -r '.[][].slot |= sort_by(.name)' > "$tmp" if [ -n "$KLISH_PARAM_name" ]; then - cat "$tmp" | /usr/libexec/statd/cli-pretty "infix-system" -n "$KLISH_PARAM_name" + cat "$tmp" | /usr/libexec/statd/cli-pretty "show-software" -n "$KLISH_PARAM_name" else cat "$tmp" | /usr/libexec/statd/cli-pretty "show-software" fi diff --git a/src/statd/python/cli_pretty/cli_pretty.py b/src/statd/python/cli_pretty/cli_pretty.py index 29e2486b8..f485fadad 100755 --- a/src/statd/python/cli_pretty/cli_pretty.py +++ b/src/statd/python/cli_pretty/cli_pretty.py @@ -691,12 +691,21 @@ def show_software(json, name): print("Error, cannot find infix-system:software") sys.exit(1) - slots = get_json_data({}, json, 'ietf-system:system-state', 'infix-system:software', 'slot') + software = get_json_data({}, json, 'ietf-system:system-state', 'infix-system:software') + slots = software.get("slot") + boot_order = software.get("boot-order", ["Unknown"]) if name: slot = find_slot(slots, name) if slot: slot.detail() else: + print(Decore.invert("BOOT ORDER")) + order="" + for boot in boot_order: + order+=f"{boot.strip()} " + print(order) + print("") + hdr = (f"{'NAME':<{PadSoftware.name}}" f"{'STATE':<{PadSoftware.state}}" f"{'VERSION':<{PadSoftware.version}}" @@ -773,10 +782,12 @@ def main(): parser_show_software = subparsers.add_parser('show-software', help='Show software versions') parser_show_software.add_argument('-n', '--name', help='Slotname') - parser_show_routing_table = subparsers.add_parser('show-hardware', help='Show USB ports') + parser_show_hardware = subparsers.add_parser('show-hardware', help='Show USB ports') parser_show_ntp_sources = subparsers.add_parser('show-ntp', help='Show NTP sources') + parser_show_boot_order = subparsers.add_parser('show-boot-order', help='Show NTP sources') + args = parser.parse_args() UNIT_TEST = args.test @@ -793,7 +804,7 @@ def main(): elif args.command == "show-ntp": show_ntp(json_data) else: - print(f"Error, unknown command {args.command}") + print(f"Error, unknown command '{args.command}'") sys.exit(1) diff --git a/src/statd/python/yanger/yanger.py b/src/statd/python/yanger/yanger.py index 5f39f222e..401d6bdca 100755 --- a/src/statd/python/yanger/yanger.py +++ b/src/statd/python/yanger/yanger.py @@ -17,6 +17,23 @@ def datetime_now(): return datetime(2023, 1, 1, 12, 0, 0, tzinfo=timezone.utc) return datetime.now(timezone.utc) +def uboot_get_boot_order(): + data = run_cmd("fw_printenv BOOT_ORDER".split(), "boot-order.txt") + for line in data: + if "BOOT_ORDER" in line: + return line.strip().split("=")[1].split() + + raise Exception + +def grub_get_boot_order(): + data = run_cmd("grub-editenv /mnt/aux/grub/grubenv list".split(), None) # No need for testfile, will be returned from uboot + + for line in data: + if "ORDER" in line: + return line.split("=")[1].strip().split() + + raise Exception + def json_get_yang_type(iface_in): if iface_in['link_type'] == "loopback": return "infix-if-type:loopback" @@ -1091,28 +1108,46 @@ def add_system_software_slots(out, data): new["class"] = slot[key].get("class") new["state"] = slot[key].get("state") new["bundle"] = {} + slot_status=value.get("slot_status", {}) + if slot_status.get("bundle", {}).get("compatible"): + new["bundle"]["compatible"] = slot_status.get("bundle", {}).get("compatible") + if slot_status.get("bundle", {}).get("version"): + new["bundle"]["version"] = slot_status.get("bundle", {}).get("version") + if slot_status.get("checksum", {}).get("size"): + new["size"] = str(slot_status.get("checksum", {}).get("size")) + if slot_status.get("checksum", {}).get("sha256"): + new["sha256"] = slot_status.get("checksum", {}).get("sha256") - if value.get("slot_status",{}).get("bundle", {}).get("compatible"): - new["bundle"]["compatible"] = value.get("slot_status",{}).get("bundle", {}).get("compatible") - if value.get("slot_status", {}).get("bundle", {}).get("version"): - new["bundle"]["version"] = value.get("slot_status", {}).get("bundle", {}).get("version") - if value.get("checksum", {}).get("size"): - new["size"] = value.get("checksum", {}).get("size") - if value.get("checksum", {}).get("sha256"): - new["sha256"] = value.get("checksum", {}).get("sha256") new["installed"] = {} - if value.get("installed", {}).get("timestamp"): - new["installed"]["datetime"] = value.get("installed", {}).get("timestamp") - if value.get("installed", {}).get("count"): - new["installed"]["count"] = value.get("installed", {}).get("count") + if slot_status.get("installed", {}).get("timestamp"): + new["installed"]["datetime"] = slot_status.get("installed", {}).get("timestamp") + + if slot_status.get("installed", {}).get("count"): + new["installed"]["count"] = slot_status.get("installed", {}).get("count") + new["activated"] = {} - if value.get("activated", {}).get("timestamp"): - new["activated"]["datetime"] = value.get("activated", {}).get("timestamp") - if value.get("activated", {}).get("count"): - new["activated"]["count"] = value.get("activated", {}).get("count") + if slot_status.get("activated", {}).get("timestamp"): + new["activated"]["datetime"] = slot_status.get("activated", {}).get("timestamp") + + if slot_status.get("activated", {}).get("count"): + new["activated"]["count"] = slot_status.get("activated", {}).get("count") slots.append(new) out["slot"] = slots +def get_system_software_boot_order(): + order = None + try: + order = uboot_get_boot_order() + except: + pass + try: + if order is None: + order = grub_get_boot_order() + except: + pass + + return order + def add_system_software(out): software = {} try: @@ -1120,6 +1155,9 @@ def add_system_software(out): software["compatible"] = data["compatible"] software["variant"] = data["variant"] software["booted"] = data["booted"] + boot_order = get_system_software_boot_order() + if not boot_order is None: + software["boot-order"] = boot_order add_system_software_slots(software, data) except subprocess.CalledProcessError: pass # Maybe an upgrade i progress, then rauc does not respond diff --git a/test/case/cli/cli-output/show-software.txt b/test/case/cli/cli-output/show-software.txt new file mode 100644 index 000000000..66deb741d --- /dev/null +++ b/test/case/cli/cli-output/show-software.txt @@ -0,0 +1,6 @@ +BOOT ORDER +net primary secondary + +NAME STATE VERSION DATE  +secondary inactive pr873.2a39a38 2024-12-16T14:40:54Z +primary inactive pr871.a4ef38f 2024-12-13T20:00:42Z diff --git a/test/case/cli/run.sh b/test/case/cli/run.sh index 5d206c4f5..8c56b3c05 100755 --- a/test/case/cli/run.sh +++ b/test/case/cli/run.sh @@ -60,7 +60,9 @@ if [ $# -eq 2 ] && [ $1 = "update" ]; then elif [ $2 = "show-bridge-mdb" ]; then "$SR_EMULATOR_TOOL" | "$CLI_PRETTY_TOOL" "show-bridge-mdb" > "$CLI_OUTPUT_PATH/show-bridge-mdb.txt" elif [ $2 = "show-ntp" ]; then - "$SR_EMULATOR_TOOL" | "$CLI_PRETTY_TOOL" "show-ntp" > "$CLI_OUTPUT_PATH/show-ntp.txt" + "$SR_EMULATOR_TOOL" | "$CLI_PRETTY_TOOL" "show-ntp" > "$CLI_OUTPUT_PATH/show-ntp.txt" + elif [ $2 = "show-software" ]; then + "$SR_EMULATOR_TOOL" | "$CLI_PRETTY_TOOL" "show-software" > "$CLI_OUTPUT_PATH/show-software.txt" else echo "Unsupported cli-pretty command $2" exit 1 @@ -69,7 +71,7 @@ if [ $# -eq 2 ] && [ $1 = "update" ]; then exit 0 fi -echo "1..11" +echo "1..12" echo "# Running:" # Show interfaces @@ -101,6 +103,16 @@ if ! diff -u "$CLI_OUTPUT_PATH/show-ntp.txt" "$CLI_OUTPUT_FILE"; then fi ok "\"show ntp\" output looks intact" +# Show software +echo "# $SR_EMULATOR_TOOL | $CLI_PRETTY_TOOL show-software" +"$SR_EMULATOR_TOOL" | "$CLI_PRETTY_TOOL" "show-software" > "$CLI_OUTPUT_FILE" + +if ! diff -u "$CLI_OUTPUT_PATH/show-software.txt" "$CLI_OUTPUT_FILE"; then + print_update_txt + fail "\"show software\" output has changed" +fi +ok "\"show software\" output looks intact" + # Show ipv4 routes echo "# $SR_EMULATOR_TOOL | $CLI_PRETTY_TOOL -t show-routing-table -i ipv4" "$SR_EMULATOR_TOOL" | "$CLI_PRETTY_TOOL" "-t" "show-routing-table" -i "ipv4" > "$CLI_OUTPUT_FILE" diff --git a/test/case/cli/system-output/boot-order.txt b/test/case/cli/system-output/boot-order.txt new file mode 100644 index 000000000..72561adc8 --- /dev/null +++ b/test/case/cli/system-output/boot-order.txt @@ -0,0 +1 @@ +BOOT_ORDER=net primary secondary diff --git a/test/case/cli/system-output/rauc-status.json b/test/case/cli/system-output/rauc-status.json index 2a1c36eeb..14418a7e3 100644 --- a/test/case/cli/system-output/rauc-status.json +++ b/test/case/cli/system-output/rauc-status.json @@ -1 +1 @@ -{"compatible":"infix-x86_64","variant":"","booted":"primary","boot_primary":"rootfs.0","slots":[{"rootfs.1":{"class":"rootfs","device":"/dev/disk/by-partlabel/secondary","type":"raw","bootname":"secondary","state":"inactive","parent":null,"mountpoint":null,"boot_status":"good"}},{"rootfs.0":{"class":"rootfs","device":"/dev/disk/by-partlabel/primary","type":"raw","bootname":"primary","state":"booted","parent":null,"mountpoint":null,"boot_status":"good"}},{"net.0":{"class":"net","device":"/dev/ram0","type":"raw","bootname":"net","state":"inactive","parent":null,"mountpoint":null,"boot_status":"good"}}]} +{"compatible":"infix-aarch64","variant":"","booted":"net","boot_primary":"net.0","slots":[{"rootfs.1":{"class":"rootfs","device":"/dev/disk/by-partlabel/secondary","type":"raw","bootname":"secondary","state":"inactive","parent":null,"mountpoint":null,"boot_status":"bad","slot_status":{"bundle":{"compatible":"infix-aarch64","version":"pr873.2a39a38","hash":"99a9543fe85a2b32a4a28409f7103099fd8cfce3f3bbccb5175ace74e7bf9ea6"},"checksum":{"sha256":"d2595e8af8468c19a5da6c3fffbf27ff8e00d7ac2559a87f60591829151fd7e3","size":59707392},"installed":{"timestamp":"2024-12-16T14:40:54Z","count":12},"activated":{"timestamp":"2024-12-16T14:40:54Z","count":12},"status":"ok"}}},{"rootfs.0":{"class":"rootfs","device":"/dev/disk/by-partlabel/primary","type":"raw","bootname":"primary","state":"inactive","parent":null,"mountpoint":null,"boot_status":"bad","slot_status":{"bundle":{"compatible":"infix-aarch64","version":"pr871.a4ef38f","hash":"d36189afff31ac1193ee7eda161f7e9b2007df08ccdc0014cfa231f9a836780a"},"checksum":{"sha256":"d78a9ef52f08238972b6b9151c381327dd0c40e410f9ed4634e379056f9bacd8","size":59699200},"installed":{"timestamp":"2024-12-13T20:00:42Z","count":3},"activated":{"timestamp":"2024-12-13T20:00:42Z","count":4},"status":"ok"}}},{"net.0":{"class":"net","device":"/dev/ram0","type":"raw","bootname":"net","state":"booted","parent":null,"mountpoint":null,"boot_status":"good","slot_status":{"bundle":{"compatible":null}}}}]} From 8e38b34c55a3621bd82e5eee892a6190a7a68cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= Date: Tue, 17 Dec 2024 14:40:52 +0100 Subject: [PATCH 2/4] doc: Add new boot order to the Changelog --- doc/ChangeLog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/ChangeLog.md b/doc/ChangeLog.md index e9d2a05ec..517a92a46 100644 --- a/doc/ChangeLog.md +++ b/doc/ChangeLog.md @@ -13,6 +13,8 @@ All notable changes to the project are documented in this file. as "reflector" and filtering of reflected services. Issue #678 - Review of default `sysctl` settings, issue #829 - Upgrade Linux kernel to 6.12.3 (LTS) + - Add the possibility to change the boot order for the system with a + RPC and add boot order to operational datastore. ### Fixes From a90294fe0845fb0df6b68bec3bac8d49aab3273c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= Date: Thu, 19 Dec 2024 08:39:05 +0100 Subject: [PATCH 3/4] test: infamy: Add optional test cleanup If a test need to clean up itself disregarding test status, it can add an optional test-cleanup phase. This is useful if the test in some circomstances leave the device in a bad state. This can be used to restore the unit to its ordinary state. --- test/infamy/tap.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/infamy/tap.py b/test/infamy/tap.py index 42a2ed610..5c805a022 100644 --- a/test/infamy/tap.py +++ b/test/infamy/tap.py @@ -13,8 +13,17 @@ def __init__(self, output=sys.stdout): if self.out == sys.stdout: sys.stdout = self.commenter + self.test_cleanup=[] self.steps = 0 + def push_test_cleanup(self, fn): + self.test_cleanup.append(fn) + + def cleanup(self): + infamy.netns.IsolatedMacVlans.Cleanup() + for test_cleanup in reversed(self.test_cleanup): + test_cleanup() + def __enter__(self): now = datetime.datetime.now().strftime("%F %T") self.out.write(f"# Starting ({now})\n") @@ -26,7 +35,7 @@ def __exit__(self, _, e, __): self.out.write(f"# Exiting ({now})\n") self.out.flush() - infamy.netns.IsolatedMacVlans.Cleanup() + self.cleanup() if not e: self._not_ok("Missing explicit test result\n") From e00737ef78d7393a820ff09aa8f98592e34d0e16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= Date: Thu, 19 Dec 2024 09:41:14 +0100 Subject: [PATCH 4/4] test: Refactor upgrade test * Use new cleanup in infamy to ensure the boot order gets restored * Use new boot order in operational and use RPC to set boot order to remove all SSH commands. --- test/case/ietf_system/upgrade/Readme.adoc | 2 - test/case/ietf_system/upgrade/test.py | 73 ++++++++-------------- test/case/ietf_system/upgrade/topology.svg | 39 +++++++----- test/infamy/restconf.py | 3 + test/infamy/transport.py | 4 ++ 5 files changed, 58 insertions(+), 63 deletions(-) diff --git a/test/case/ietf_system/upgrade/Readme.adoc b/test/case/ietf_system/upgrade/Readme.adoc index b295c8197..47e8c178a 100644 --- a/test/case/ietf_system/upgrade/Readme.adoc +++ b/test/case/ietf_system/upgrade/Readme.adoc @@ -20,8 +20,6 @@ endif::topdoc[] . Wait for upgrade to finish . Verify boot order has changed and reboot . Verify that the partition is the booted -. Restore boot order to original configured -. Verify the boot order is the orignal configured <<< diff --git a/test/case/ietf_system/upgrade/test.py b/test/case/ietf_system/upgrade/test.py index 6535dc433..e4cf8397a 100755 --- a/test/case/ietf_system/upgrade/test.py +++ b/test/case/ietf_system/upgrade/test.py @@ -25,30 +25,30 @@ BUNDLEDIR, "package" ) +def get_boot_order(target): + oper = target.get_dict("/system-state/software") + return " ".join(oper["system-state"]["software"]["boot-order"]) + +def set_boot_order(target, order): + target.call_dict("infix-system", { + "set-boot-order": { + "boot-order": order.split(" ") + } + }) -class Uboot: - def __init__(self, ssh): - self.ssh=ssh - - def get_boot_order(self): - order=self.ssh.runsh("sudo fw_printenv BOOT_ORDER").stdout.split("=") - return order[1].strip() - - def set_boot_order(self, order): - return self.ssh.run(f"sudo fw_setenv BOOT_ORDER '{order}'".split()).returncode - -class Grub: - def __init__(self, ssh): - self.ssh = ssh - def get_boot_order(self): - lines=self.ssh.runsh("grub-editenv /mnt/aux/grub/grubenv list").stdout.split("\n") - for line in lines: - if "ORDER" in line: - return line.split("=")[1].strip() +def cleanup(env, old_bootorder): + print(f"Restore boot order to {old_bootorder}") + target = env.attach("target", "mgmt", "netconf") + set_boot_order(target, old_bootorder) + target.reboot() + if not wait_boot(target, env): + test.fail() + target = env.attach("target", "mgmt", "netconf") - def set_boot_order(self, order): - return self.ssh.run(f"sudo grub-editenv /mnt/aux/grub/grubenv set ORDER='{order}'".split()).returncode + print("Verify the boot order is the orignal configured") + order = get_boot_order(target) + assert order == old_bootorder, f"Unexpected bootorder: {repr(order)}" with infamy.Test() as test: with test.step("Set up topology and attach to target DUT"): @@ -65,20 +65,13 @@ def set_boot_order(self, order): os.symlink(os.path.abspath(env.args.package), PKGPATH) target = env.attach("target", "mgmt", "netconf") - target_ssh = env.attach("target", "mgmt", "ssh") - if target_ssh.run("test -e /sys/firmware/devicetree/base/chosen/u-boot,version".split()).returncode == 0: - bootloader=Uboot(target_ssh) - elif target_ssh.run("test -e /mnt/aux/grub/grubenv".split()).returncode == 0: - bootloader=Grub(target_ssh) - else: - print("No supported bootloader found") - test.skip() - old_bootorder=bootloader.get_boot_order() + old_bootorder=get_boot_order(target) print(f"Initial bootorder: {repr(old_bootorder)}") _, hport = env.ltop.xlate("host", "data") _, tport = env.ltop.xlate("target", "data") + test.push_test_cleanup(lambda: cleanup(env, old_bootorder)) netns = infamy.IsolatedMacVlan(hport).start() netns.addip("192.168.0.1") @@ -130,7 +123,9 @@ def set_boot_order(self, order): test.fail() with test.step("Verify boot order has changed and reboot"): - assert(old_bootorder != bootloader.get_boot_order()) + print(get_boot_order(target)) + print(old_bootorder) + assert(old_bootorder != get_boot_order(target)) target.reboot() if not wait_boot(target, env): @@ -139,24 +134,10 @@ def set_boot_order(self, order): with test.step("Verify that the partition is the booted"): - should_boot=bootloader.get_boot_order().split()[0] + should_boot=get_boot_order(target).split()[0] oper = target.get_dict("/system-state/software") booted = oper["system-state"]["software"]["booted"] print(f"Should boot: {should_boot}, booted: {booted}") assert(booted == should_boot) - with test.step("Restore boot order to original configured"): - print(f"Restore boot order to {old_bootorder}") - if bootloader.set_boot_order(old_bootorder) != 0: - test.fail() - target = env.attach("target", "mgmt", "netconf") - target.reboot() - if not wait_boot(target, env): - test.fail() - target = env.attach("target", "mgmt", "netconf") - - with test.step("Verify the boot order is the orignal configured"): - order = bootloader.get_boot_order() - assert order == old_bootorder, f"Unexpected bootorder: {repr(order)}" - test.succeed() diff --git a/test/case/ietf_system/upgrade/topology.svg b/test/case/ietf_system/upgrade/topology.svg index cc6ebcb43..ff3d246be 100644 --- a/test/case/ietf_system/upgrade/topology.svg +++ b/test/case/ietf_system/upgrade/topology.svg @@ -2,32 +2,41 @@ - - - -1x1 - + + + +1x2 + host - -host - -mgmt + +host + +mgmt + +data target - -mgmt - -target + +mgmt + +data + +target host:mgmt--target:mgmt - + + + + +host:data--target:data + diff --git a/test/infamy/restconf.py b/test/infamy/restconf.py index 52b3aef78..4cb7de713 100644 --- a/test/infamy/restconf.py +++ b/test/infamy/restconf.py @@ -302,6 +302,9 @@ def put_config_dict(self, modname, edit): return self.put_datastore("running", data) + def call_dict(self, model, call): + pass # Need implementation + def call_rpc(self, rpc): """Actually send a POST to RESTCONF server""" url = f"{self.rpc_url}/{rpc}" diff --git a/test/infamy/transport.py b/test/infamy/transport.py index 61daae9d8..3c754a94a 100644 --- a/test/infamy/transport.py +++ b/test/infamy/transport.py @@ -47,6 +47,10 @@ def get_current_time_with_offset(self): """Needed since libyang is too nice and removes the original offset""" pass + @abstractmethod + def call_dict(self, module, call): + pass + @abstractmethod def call_action(self, xpath): pass