Switch upgrade using netconf API call to upgrade switches via python script
The following two python scripts can be used to remote initiate software upgrade:
Note: make sure to install all necessary libraries to run the script.
Method 1: transfer the image and then initiate the installation: import paramiko from ncclient import manager from ncclient.xml_ import to_ele import os DEVICE_IP = "<switch IP>" USERNAME = "user" PASSWORD = "password" LOCAL_FILE = "/var/tmp/jinstall-host-qfx-5e-x86-64-21.4R3-S10.13-secure-signed.tgz" REMOTE_FILE = "/var/tmp/jinstall-host-qfx-5e-x86-64-21.4R3-S10.13-secure-signed.tgz" # -------------------------- # STEP 1: SCP transfer # -------------------------- print(" Transferring image via SCP...") ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(DEVICE_IP, username=USERNAME, password=PASSWORD) scp = paramiko.SFTPClient.from_transport(ssh.get_transport()) scp.put(LOCAL_FILE, REMOTE_FILE) scp.close() ssh.close() print(" Transfer complete") # -------------------------- # STEP 2: NETCONF install # -------------------------- rpc = f"""<request-package-add> <package-name>{REMOTE_FILE}</package-name> <no-copy/> <force-host/> </request-package-add>""" print(" Starting installation...") with manager.connect(host=DEVICE_IP, port=830, username=USERNAME, password=PASSWORD, hostkey_verify=False, timeout=1800) as m: response = m.dispatch(to_ele(rpc)) print(response) print(" Rebooting...") m.dispatch(to_ele("<request-system-reboot/>"))
>>> Results:
Results from method #1: [12:09:34.945] (netconf-env) root@ubuntu:~# python3 /var/tmp/install_214_1_2.py [12:09:35.103] ?? Transferring image via SCP... [12:16:23.846] ? Transfer complete [12:16:23.846] ?? Starting installation... [12:21:16.966] #<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/18.4R3/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:07faa618-194f-439d-a7d4-761a39fa5103"> [12:21:16.974] <pipe> [12:21:16.974] <more-no-more/> [12:21:16.975] </pipe> [12:21:16.975] <cli> [12:21:16.975] <ignore-signals> [12:21:16.975] hup [12:21:16.975] </ignore-signals> [12:21:16.975] </cli> [12:21:16.975] <output> [12:21:16.975] Verified jinstall-host-qfx-5e-x86-64-21.4R3-S10.13-secure-signed signed by PackageProductionECP256_2025 method ECDSA256+SHA256 [12:21:16.976] Forcing the Host Upgrade for Non Issu updates... [12:21:16.976] Pushing Junos image package to the host... [12:21:16.976] Installing /var/tmp/install-media-qfx-5e-junos-21.4R3-S10.13-secure.tgz [12:21:16.976] Extracting the package ... [12:21:16.977] [12:21:16.977] ============================================ [12:21:16.977] Host OS upgrade is FORCED [12:21:16.978] Current Host kernel version : 3.14.52-rt50-WR7.0.0.9_ovp [12:21:16.978] Package Host kernel version : 3.14.52-rt50-WR7.0.0.9_ovp [12:21:16.978] Current Host version : 3.1.0 [12:21:16.978] Package Host version : 3.1.0 [12:21:16.978] Min host version required for applications: 3.0.7 [12:21:16.978] ============================================ [12:21:16.978] [12:21:16.978] Validate linux image... [12:21:16.978] upgrade_platform: ------------------- [12:21:16.978] upgrade_platform: Parameters passed: [12:21:16.978] upgrade_platform: silent=0 [12:21:16.978] upgrade_platform: package=/var/tmp/tmp.wBY4vVbzj4junos_cli_upg/jinstall-qfx-5e-junos-21.4R3-S10.13-secure-linux.tgz [12:21:16.980] upgrade_platform: clean install=0 [12:21:16.980] upgrade_platform: on primary =0 [12:21:16.980] upgrade_platform: clean upgrade=0 [12:21:16.980] upgrade_platform: Need reboot after staging=1 [12:21:16.980] upgrade_platform: ------------------- [12:21:16.980] upgrade_platform: [12:21:16.980] /var/tmp/tmp.wBY4vVbzj4junos_cli_upg/upgrade_platform: line 366: is_absinthe_family: command not found [12:21:16.980] upgrade_platform: Checking input /var/tmp/tmp.wBY4vVbzj4junos_cli_upg/jinstall-qfx-5e-junos-21.4R3-S10.13-secure-linux.tgz ... [12:21:16.980] upgrade_platform: Input package /var/tmp/tmp.wBY4vVbzj4junos_cli_upg/jinstall-qfx-5e-junos-21.4R3-S10.13-secure-linux.tgz is valid. [12:21:16.980] Secure Boot is enforced. [12:21:16.981] ALLOW:usr/secureboot/grub/BOOTX64.EFI [12:21:16.981] ALLOW:boot/bzImage-intel-x86-64.bin [12:21:16.981] ALLOW:boot/initramfs.cpio.gz [12:21:16.981] Setting up Junos host applications for installation ... [12:21:16.983] Current junos instance is 0 [12:21:16.983] Installing Host OS ... [12:21:16.983] upgrade_platform: ------------------- [12:21:16.983] upgrade_platform: Parameters passed: [12:21:16.984] upgrade_platform: silent=0 [12:21:16.984] upgrade_platform: package=/var/tmp/jinstall-qfx-5e-junos-21.4R3-S10.13-secure-linux.tgz [12:21:16.984] upgrade_platform: clean install=0 [12:21:16.984] upgrade_platform: on primary =0 [12:21:16.984] upgrade_platform: clean upgrade=0 [12:21:16.984] upgrade_platform: Need reboot after staging=0 [12:21:16.984] upgrade_platform: ------------------- [12:21:16.985] upgrade_platform: [12:21:16.985] /var/tmp/upgrade_platform: line 366: is_absinthe_family: command not found [12:21:16.985] upgrade_platform: Checking input /var/tmp/jinstall-qfx-5e-junos-21.4R3-S10.13-secure-linux.tgz ... [12:21:16.986] upgrade_platform: Input package /var/tmp/jinstall-qfx-5e-junos-21.4R3-S10.13-secure-linux.tgz is valid. [12:21:16.986] Secure Boot is enforced. [12:21:16.988] ALLOW:usr/secureboot/grub/BOOTX64.EFI [12:21:16.988] ALLOW:boot/bzImage-intel-x86-64.bin [12:21:16.988] ALLOW:boot/initramfs.cpio.gz [12:21:16.988] upgrade_platform: Backing up boot assets.. [12:21:16.988] bzImage-intel-x86-64.bin: OK [12:21:16.988] bzImage-intel-x86-64.bin.psig: OK [12:21:16.988] initramfs.cpio.gz: OK [12:21:16.988] initramfs.cpio.gz.psig: OK [12:21:16.988] version.txt: OK [12:21:16.988] upgrade_platform: Checksum verified and OK... [12:21:16.988] /boot [12:21:16.988] upgrade_platform: Backup completed [12:21:16.988] upgrade_platform: Staging the upgrade package - /var/tmp/jinstall-qfx-5e-junos-21.4R3-S10.13-secure-linux.tgz.. [12:21:16.988] ./ [12:21:16.988] ./version.txt [12:21:16.989] ./platform_info [12:21:16.990] ./host-version [12:21:16.990] ./initramfs.cpio.gz.psig [12:21:16.990] ./grub/ [12:21:16.990] ./grub/grub.efi [12:21:16.990] ./grub/grub.conf [12:21:16.990] ./upgrade_platform [12:21:16.990] ./bzImage-intel-x86-64.bin.psig [12:21:16.990] ./initramfs.cpio.gz [12:21:16.990] ./linux.checksum [12:21:16.990] ./bzImage-intel-x86-64.bin [12:21:16.990] ./initrd.cpio.gz [12:21:16.990] bzImage-intel-x86-64.bin: OK [12:21:16.990] bzImage-intel-x86-64.bin.psig: OK [12:21:16.990] initramfs.cpio.gz: OK [12:21:16.990] initramfs.cpio.gz.psig: OK [12:21:16.995] version.txt: OK [12:21:16.995] upgrade_platform: Checksum verified and OK... [12:21:16.995] /var/tmp/upgrade_platform: line 630: is_with_onie_with_uefi: command not found [12:21:16.995] 1062851 blocks [12:21:16.995] upgrade_platform: Staging of /var/tmp/jinstall-qfx-5e-junos-21.4R3-S10.13-secure-linux.tgz completed [12:21:16.995] upgrade_platform: System need *REBOOT* to complete the upgrade [12:21:16.995] upgrade_platform: Run upgrade_platform with option -r | --rollback to rollback the upgrade [12:21:16.995] [12:21:16.995] Host OS upgrade staged. Reboot the system to complete installation! ---------------------
Method 2 - Image is locally on the switch:
from ncclient import manager from ncclient.xml_ import to_ele import xml.etree.ElementTree as ET import sys DEVICE = { "host": "switch IP", "port": 830, "username": "user", "password": "password" } IMAGE_PATH = "/var/tmp/jinstall-host-qfx-5e-x86-64-21.4R3-S10.13-secure-signed.tgz" install_rpc = f"""<request-package-add> <package-name>{IMAGE_PATH}</package-name> <no-copy/> <force-host/> </request-package-add>""" reboot_rpc = "<request-system-reboot/>" def check_install_success(response_xml): """Parse NETCONF reply and determine success""" root = ET.fromstring(response_xml) ns = {'nc': 'urn:ietf:params:xml:ns:netconf:base:1.0'} result = root.find(".//nc:package-result", ns) output = root.find(".//nc:output", ns) print("\n--- DEVICE OUTPUT ---") if output is not None: print(output.text.strip()) print("---------------------\n") if result is not None and result.text == "0": return True else: return False try: with manager.connect(host=DEVICE["host"], port=DEVICE["port"], username=DEVICE["username"], password=DEVICE["password"], hostkey_verify=False, timeout=1800) as m: print("x Starting software install...\n") response = m.dispatch(to_ele(install_rpc)) response_xml = str(response) if check_install_success(response_xml): print("x Install SUCCESS") print("x Initiating reboot...") m.dispatch(to_ele(reboot_rpc)) print("x Reboot command sent (device will disconnect)") else: print("x Install FAILED — not rebooting") sys.exit(1) except Exception as e: print(f"x Error: {e}") sys.exit(1) ------------------- (netconf-env) root@ubuntu:~# python3 /var/tmp/install_214_1.py x Starting software install... --- DEVICE OUTPUT --- Verified jinstall-host-qfx-5e-x86-64-21.4R3-S10.13-secure-signed signed by PackageProductionECP256_2025 method ECDSA256+SHA256 Forcing the Host Upgrade for Non Issu updates... Pushing Junos image package to the host... Installing /var/tmp/install-media-qfx-5e-junos-21.4R3-S10.13-secure.tgz Extracting the package ... ============================================ Host OS upgrade is FORCED Current Host kernel version : 3.14.52-rt50-WR7.0.0.9_ovp Package Host kernel version : 3.14.52-rt50-WR7.0.0.9_ovp Current Host version : 3.1.0 Package Host version : 3.1.0 Min host version required for applications: 3.0.7 ============================================ Validate linux image... upgrade_platform: ------------------- upgrade_platform: Parameters passed: upgrade_platform: silent=0 upgrade_platform: package=/var/tmp/tmp.hQ6i3Yfp5ijunos_cli_upg/jinstall-qfx-5e-junos-21.4R3-S10.13-secure-linux.tgz upgrade_platform: clean install=0 upgrade_platform: on primary =0 upgrade_platform: clean upgrade=0 upgrade_platform: Need reboot after staging=1 upgrade_platform: ------------------- upgrade_platform: /var/tmp/tmp.hQ6i3Yfp5ijunos_cli_upg/upgrade_platform: line 366: is_absinthe_family: command not found upgrade_platform: Checking input /var/tmp/tmp.hQ6i3Yfp5ijunos_cli_upg/jinstall-qfx-5e-junos-21.4R3-S10.13-secure-linux.tgz ... upgrade_platform: Input package /var/tmp/tmp.hQ6i3Yfp5ijunos_cli_upg/jinstall-qfx-5e-junos-21.4R3-S10.13-secure-linux.tgz is valid. Secure Boot is enforced. ALLOW:usr/secureboot/grub/BOOTX64.EFI ALLOW:boot/bzImage-intel-x86-64.bin ALLOW:boot/initramfs.cpio.gz Setting up Junos host applications for installation ... Current junos instance is 0 Installing Host OS ... upgrade_platform: ------------------- upgrade_platform: Parameters passed: upgrade_platform: silent=0 upgrade_platform: package=/var/tmp/jinstall-qfx-5e-junos-21.4R3-S10.13-secure-linux.tgz upgrade_platform: clean install=0 upgrade_platform: on primary =0 upgrade_platform: clean upgrade=0 upgrade_platform: Need reboot after staging=0 upgrade_platform: ------------------- upgrade_platform: /var/tmp/upgrade_platform: line 366: is_absinthe_family: command not found upgrade_platform: Checking input /var/tmp/jinstall-qfx-5e-junos-21.4R3-S10.13-secure-linux.tgz ... upgrade_platform: Input package /var/tmp/jinstall-qfx-5e-junos-21.4R3-S10.13-secure-linux.tgz is valid. Secure Boot is enforced. ALLOW:usr/secureboot/grub/BOOTX64.EFI ALLOW:boot/bzImage-intel-x86-64.bin ALLOW:boot/initramfs.cpio.gz upgrade_platform: Backing up boot assets.. bzImage-intel-x86-64.bin: OK initramfs.cpio.gz: OK version.txt: OK upgrade_platform: Checksum verified and OK... /boot upgrade_platform: Backup completed upgrade_platform: Staging the upgrade package - /var/tmp/jinstall-qfx-5e-junos-21.4R3-S10.13-secure-linux.tgz.. ./ ./version.txt ./platform_info ./host-version ./initramfs.cpio.gz.psig ./grub/ ./grub/grub.efi ./grub/grub.conf ./upgrade_platform ./bzImage-intel-x86-64.bin.psig ./initramfs.cpio.gz ./linux.checksum ./bzImage-intel-x86-64.bin ./initrd.cpio.gz bzImage-intel-x86-64.bin: OK bzImage-intel-x86-64.bin.psig: OK initramfs.cpio.gz: OK initramfs.cpio.gz.psig: OK version.txt: OK upgrade_platform: Checksum verified and OK... /var/tmp/upgrade_platform: line 630: is_with_onie_with_uefi: command not found 1062851 blocks upgrade_platform: Staging of /var/tmp/jinstall-qfx-5e-junos-21.4R3-S10.13-secure-linux.tgz completed upgrade_platform: System need *REBOOT* to complete the upgrade upgrade_platform: Run upgrade_platform with option -r | --rollback to rollback the upgrade Host OS upgrade staged. Reboot the system to complete installation! ---------------------