Description

Switch upgrade using netconf API call to upgrade switches via python script

Solution

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!
		---------------------

 

Modification History

2026-05-27 : Article Created