Skip to content

Add Juniper ISSU and NSSU support#400

Draft
mattmiller87 wants to merge 7 commits into
developfrom
u/mattmiller/NAPPS-1032-juniper-install
Draft

Add Juniper ISSU and NSSU support#400
mattmiller87 wants to merge 7 commits into
developfrom
u/mattmiller/NAPPS-1032-juniper-install

Conversation

@mattmiller87

@mattmiller87 mattmiller87 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

New Pull Request

This PR adds Juniper install options for in-service software upgrade and nonstop software upgrade for SRX and EX devices.

This is in testing and may need some revisions.

  • EX Virtual-Chassis
  • SRX Chassis Cluster
  • EX single device

SDK docs - https://junos-pyez.readthedocs.io/en/2.8.2/jnpr.junos.utils.html#jnpr.junos.utils.sw.SW.install

rpc.cli() - used to run commands not available in the sdk.

Change Notes

Add issu and nssu choices on install_os.
Add install_os_multi which performs an os change on multiple devices without using nssu.
Add request_system_snapshot to enforce best practices with dual partitions.

Justification

@mattmiller87 mattmiller87 force-pushed the u/mattmiller/NAPPS-1032-juniper-install branch from d366b46 to ff4f8a5 Compare July 7, 2026 17:53
@jtdub jtdub requested review from Copilot and jtdub July 7, 2026 21:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the Junos device driver to support Juniper ISSU/NSSU upgrade flows and adds a system snapshot helper intended to enforce dual-partition best practices during upgrades.

Changes:

  • Add issu / nssu options to JunosDevice.install_os() and adjust upgrade/reboot handling logic.
  • Add JunosDevice.install_os_multi() to perform multi-member (virtual-chassis) upgrades without NSSU.
  • Add request_system_snapshot() plus polling-based verification for snapshot completion.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.

File Description
pyntc/devices/jnpr_device.py Adds ISSU/NSSU install options, a multi-device install flow, and snapshot request/verification helpers.
changes/mm.added Adds a changelog entry for the new Juniper install options.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +299 to +303
output = self.native.cli("show system snapshot media internal")
if "snapshot" in output.lower():
log.info("Host %s: System snapshot verified.", self.host)
return
log.debug("Host %s: Snapshot verification in progress; will retry.", self.host)
Comment on lines +305 to +307
except Exception as exc: # pylint: disable=broad-exception-caught
log.debug("Host %s: Snapshot verification poll failed (%s); will retry.", self.host, exc)

Comment thread pyntc/devices/jnpr_device.py Outdated
Comment on lines +604 to +607
# Capture pre-install state for validation after reboot
self._uptime = None
pre_install_uptime = self.uptime
pre_install_version = self.os_version
Comment thread pyntc/devices/jnpr_device.py Outdated
Comment on lines +723 to +729
if not reboot:
log.info("Host %s: OS image %s boot options set. Reboot the device to apply", self.host, image_name)
return True

self.reboot(wait_for_reload=True)
if not nssu:
self.reboot(wait_for_reload=True)

Comment thread pyntc/devices/jnpr_device.py Outdated
Comment on lines +671 to +675
except ConnectClosedError:
# Connection loss during install is expected (device reboots)
log.info(
"Host %s: Connection closed during install (expected for device reboot). "
"Waiting for device to come back online.",
Comment thread pyntc/devices/jnpr_device.py Outdated
Comment on lines +771 to +775
# Capture pre-install state
self._uptime = None
pre_install_uptime = self.uptime
pre_install_version = self.os_version

Comment thread changes/mm.added Outdated
@@ -0,0 +1 @@
Added issu and nssu upgrade choices for install on juniper devices. No newline at end of file
@mattmiller87 mattmiller87 force-pushed the u/mattmiller/NAPPS-1032-juniper-install branch 3 times, most recently from cf77af7 to e9407cc Compare July 8, 2026 13:28
@mattmiller87 mattmiller87 force-pushed the u/mattmiller/NAPPS-1032-juniper-install branch from e9407cc to 43bb7c6 Compare July 8, 2026 13:42
@jtdub jtdub requested a review from Copilot July 8, 2026 14:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

Comment on lines +872 to +874
log.info("Host %s: Rebooting device to apply OS image %s", self.host, image_name)
original_uptime = self.uptime

Comment on lines +883 to +887
# Extract target version from image name for verification
# Matches formats: 15.1R7-S2, 20.4R3, 21.4X38-D10, 18.4R2.7, etc.
match = re.search(r"(\d+\.\d+[A-Z]+[\d\.]+(?:[-][A-Z]+\d+)*)", image_name)
target_version = match.group(1) if match else None

Comment on lines +550 to +552
Raises:
OSInstallError: If snapshot verification fails or times out.
"""
Comment on lines +465 to +471
"""Check if device is in virtual-chassis or chassis-cluster configuration.

Inspects re_info from PyEZ facts to determine if multiple members are present.

Returns:
bool: True if multiple members are present, False otherwise.
"""
Comment on lines +575 to +580
with self.subTest("snapshot times out"):
mock_sleep.reset_mock()
self.device.native.cli.return_value = "No snapshots found"
with self.assertRaises(TimeoutError) as ctx:
self.device._wait_for_system_snapshot(timeout=10)
self.assertIn("did not complete", str(ctx.exception))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants