Skip to content

Forward unlink option to request-package-add RPC#1412

Draft
shigechika wants to merge 2 commits into
Juniper:masterfrom
shigechika:fix/990-no-copy-and-unlink-passthrough
Draft

Forward unlink option to request-package-add RPC#1412
shigechika wants to merge 2 commits into
Juniper:masterfrom
shigechika:fix/990-no-copy-and-unlink-passthrough

Conversation

@shigechika

Copy link
Copy Markdown
Contributor

Summary

Add an explicit unlink keyword argument to SW.install() that is forwarded to the underlying request-package-add RPC so that <unlink/> appears in the request, matching the behavior of the request system software add ... unlink CLI option.

Motivation

On low-flash devices such as EX2300 and EX3400 (/dev/gpt/junos = 1.3 GB), major version JUNOS upgrades (e.g. 22.4 → 23.4) may fail at the validation stage with:

ERROR: insufficient space for /packages/db/.../junos-runtime.tgz
software validate package-result: 1

The root cause is that PyEZ's default SW.install() path issues a request-package-add RPC without the <unlink/> element. The validation phase expands the tarball into /packages/db/... while the original .tgz still occupies space in /var/tmp, causing the peak usage to exceed the available filesystem space.

When request system software add ... unlink is invoked from the JUNOS CLI, the tarball is removed during pkgadd, reducing peak usage and letting the upgrade complete. This patch lets PyEZ callers reproduce that behavior.

RPC schema verification

I verified on a JUNOS 22.4 device (EX-family) that unlink is a valid sibling element of request-package-add, independent of no-copy / no-validate:

nuadmin@host> request system software add /var/tmp/dummy.tgz unlink no-copy no-validate | display xml rpc
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/22.4R0/junos">
    <rpc>
        <request-package-add>
                <no-copy/>
                <no-validate/>
                <unlink/>
                <package-name>/var/tmp/dummy.tgz</package-name>
        </request-package-add>
    </rpc>
    ...
</rpc-reply>

Changes

  • lib/jnpr/junos/utils/sw.py
    • SW.install() gains a new unlink: bool = False keyword argument.
    • When unlink=True, the option is injected into kwargs before pkgadd() is invoked, so every call site in install() (single RE, multi RE, VC, ISSU/NSSU, mixed VC, etc.) propagates it identically to other passthrough options like routing_instance.
    • Updated docstring with the rationale for low-flash devices.
  • tests/unit/utils/test_sw.py
    • New test_sw_install_with_unlink verifies that install(no_copy=True, unlink=True) produces a <unlink/> element in the resulting RPC, mirroring the existing test_sw_install_with_routing_instance style. Existing tests are left untouched.

Backward compatibility: unlink=False is the default and existing call sites are unaffected. All 127 unit tests in tests/unit/utils/test_sw.py pass.

Related

  • Closely related to sw.install(): no-copy argument is not passed further to rpc command #990 (no-copy argument not passed further to RPC). I deliberately scoped this PR to unlink only to keep the diff minimal and the change uncontroversial; reusing install(no_copy=True) to also emit <no-copy/> would be a behavior change of an existing parameter and would require updating the order-permutation assertions in test_sw_install_kwargs_force_host. Happy to follow up in a separate PR if maintainers prefer that direction.

Test plan

  • pytest tests/unit/utils/test_sw.py — 127 passed locally
  • Verified <unlink/> element appears in the generated RPC via mock execute
  • Verified RPC schema on a real EX-family device with | display xml rpc

🤖 Generated with Claude Code

Add an explicit unlink keyword argument to SW.install() that is
forwarded to the underlying request-package-add RPC so that
<unlink/> appears in the request, matching the behavior of the
"request system software add ... unlink" CLI option.

Useful for low-flash devices (e.g. EX2300, EX3400) where major
version upgrades may fail with "ERROR: insufficient space" during
validation because the package tarball remains on disk while its
contents are being expanded. With unlink, the tarball is removed
during pkgadd, reducing peak filesystem usage.

Related to issue Juniper#990.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@shigechika shigechika closed this May 21, 2026
@shigechika shigechika deleted the fix/990-no-copy-and-unlink-passthrough branch May 21, 2026 09:10
@shigechika shigechika restored the fix/990-no-copy-and-unlink-passthrough branch May 21, 2026 09:11
@shigechika shigechika reopened this May 21, 2026
- Add test_sw_install_without_unlink verifying that the default
  (unlink=False) does not emit <unlink/>, guarding against future
  regressions.
- Note in the docstring that unlink is intended for non-vmhost
  devices, since "request vmhost package add" does not document
  an unlink option.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.

1 participant