Skip to content

klish: stop auto-injecting exit/end when the view already declares one#159

Closed
eduardoterto wants to merge 1 commit into
sonic-net:masterfrom
terto-networks:klish/fix-duplicate-exit-and-legacy-startup
Closed

klish: stop auto-injecting exit/end when the view already declares one#159
eduardoterto wants to merge 1 commit into
sonic-net:masterfrom
terto-networks:klish/fix-duplicate-exit-and-legacy-startup

Conversation

@eduardoterto
Copy link
Copy Markdown

Summary

`klish_ins_def_cmd.py` auto-inserts a generic `<COMMAND name="exit"/>` and `<COMMAND name="end"/>` into every VIEW that has not been processed yet. The "already processed" check keys on the view name across files, not on the view's own children — so any single-file VIEW that legitimately ships its own exit (e.g. IOS-XR style hierarchies where `exit` returns to the parent VIEW rather than nesting up) ends up with two COMMANDs of the same name. klish then refuses to load the file with:

```
Error parsing XML: Duplicate COMMAND name="exit".
Error parsing XML: Node VIEW, name="config-evpn-view"
```

When that happens during klish startup the affected view becomes unusable, and any `clish_start` invocation (interactive or batch) prints the parser errors to stderr before the prompt. Batch stdin (`docker exec -i mgmt-framework /usr/sbin/cli/clish_start < cfg`) fails outright.

The original docstring already promises this guard:

if "exit" and "end" command are not already appended for the view, the script will append them for the view

This change makes the implementation match. We check the view's own COMMAND children for `name="exit"` and `name="end"` before inserting.

Discovered

First end-to-end run of `canonical-mpls` (terto-horizon `sim/canonical-mpls`), 2026-05-12. With the EVPN, OSPF, BGP, ACL, QoS, L2VPN, MPLS-LDP and segment-routing views all shipping their own exit, the bug silently broke 21 view files (108 dup COMMANDs total) on the running `mgmt-framework` container.

Test plan

  • On a running mgmt-framework with the buggy XMLs, applying the equivalent transform (remove every `COMMAND name="exit" lock="false"` where another COMMAND `name="exit"` exists in the same VIEW) unblocks `clish_start` and lets it accept batch stdin from `sim/canonical-mpls/configs/pe1.cfg`.
  • After this PR merges, rebuilding `docker-sonic-mgmt-framework` should produce XML with a single `<COMMAND name="exit"/>` per view that originally shipped one.

Out of scope (next PRs)

  • Legacy `CLI/clitree/cli-xml/startup.xml` (Dell 2019) declares `<STARTUP view="enable-view">`. The tertoos `01-exec-view.xml` declares `<STARTUP view="exec-view"/>`. klish refuses to load with two STARTUPs. Needs to be deleted on the tertoos feature branch that introduces `01-exec-view.xml`, not on master (would break upstream-aligned branches that don't have a replacement).

🤖 Generated with Claude Code

klish_ins_def_cmd.py auto-inserts a generic <COMMAND name="exit"/> and
<COMMAND name="end"/> into every VIEW that has not been processed yet.
The "already processed" check keys on the view name across files, not
on the view's own children — so any single-file VIEW that legitimately
ships its own exit (e.g. IOS-XR style hierarchies where exit returns
to the parent VIEW rather than nesting up) ends up with two COMMANDs
of the same name. klish then refuses to load the file with:

    Error parsing XML: Duplicate COMMAND name="exit"
    Error parsing XML: Node VIEW, name="config-evpn-view"

When that happens during klish startup the affected view becomes
unusable, and any clish_start invocation (interactive or batch) prints
the parser errors to stderr before the prompt. Batch stdin (e.g.
docker exec -i mgmt-framework /usr/sbin/cli/clish_start < cfg) fails
outright.

The original docstring already promises this guard:

    if "exit" and "end" command are not already appended for the view,
    the script will append them for the view

so this change makes the implementation match. We now check the view's
own COMMAND children for name="exit" and name="end" before inserting.

Discovered in the first end-to-end run of canonical-mpls (terto-horizon
sim/canonical-mpls): with the EVPN, OSPF, BGP, ACL, QoS, L2VPN, MPLS-LDP
and segment-routing views all shipping their own exit, the bug
silently broke 21 view files (108 dup COMMANDs total) on the running
mgmt-framework container.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@mssonicbld
Copy link
Copy Markdown

/azp run

@linux-foundation-easycla
Copy link
Copy Markdown

CLA Missing ID

One or more co-authors of this pull request were not found. You must specify co-authors in commit message trailer via:

Co-authored-by: name <email>

Supported Co-authored-by: formats include:

  1. Anything <id+login@users.noreply.github.com> - it will locate your GitHub user by id part.
  2. Anything <login@users.noreply.github.com> - it will locate your GitHub user by login part.
  3. Anything <public-email> - it will locate your GitHub user by public-email part. Note that this email must be made public on Github.
  4. Anything <other-email> - it will locate your GitHub user by other-email part but only if that email was used before for any other CLA as a main commit author.
  5. login <any-valid-email> - it will locate your GitHub user by login part, note that login part must be at least 3 characters long.

Alternatively, if the co-author should not be included, remove the Co-authored-by: line from the commit message.

Please update your commit message(s) by doing git commit --amend and then git push [--force] and then request re-running CLA check via commenting on this pull request:

/easycla

@eduardoterto
Copy link
Copy Markdown
Author

Sorry, intended for terto-networks fork. Closing — will reopen there.

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@eduardoterto eduardoterto deleted the klish/fix-duplicate-exit-and-legacy-startup branch May 12, 2026 20:21
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.

2 participants