Skip to content

[Nexthop][fboss2-dev] Unify agent/BGP config session + decouple ConfigSession header - #1446

Closed
hillol-nexthop wants to merge 6 commits into
meta:mainfrom
nexthop-ai:bgp-session-unify
Closed

hillol-nexthop wants to merge 6 commits into
meta:mainfrom
nexthop-ai:bgp-session-unify

Conversation

@hillol-nexthop

@hillol-nexthop hillol-nexthop commented Jul 31, 2026 •

Copy link
Copy Markdown
Contributor

Base of the fboss2-dev config protocol bgp stack (follow-up to the merged #1344). Everything above it in the list below builds on this PR, so merge this one first.

Stack (bottom → top): #1446 (this PR) → #1345 → #1391 → #1395 → #1401 → #1485 → #1475 → #1486 → #1477 → #1487 → #1488 → #1489 → #1490 → #1491

Summary

Follow-up to #1344 (BGP-aware fboss2 config session): unify the agent and BGP
domains inside ConfigSession and decouple the ConfigSession.h header from
the heavy generated thrift types.

  • Make ConfigActionLevel generic across services (review feedback below):
    HITLESS / SERVICE_RESTART / DISRUPTIVE_SERVICE_RESTART replace
    HITLESS / AGENT_WARMBOOT / AGENT_COLDBOOT (+ the bgpd-only BGP_RESTART).
    What a level means is decided per service from the (service, level) pair in
    FbossServiceUtil::restartTypeName(): agent → warmboot / coldboot, bgpd (no
    warmboot or hitless reload) → plain restart. config session commit labels
    the restarted services accordingly (wedge_agent (warmboot), bgpd (restart)).
    A session staged before this change (old level names in
    ~/.fboss2/cli_metadata.json) no longer parses and loses its recorded
    restart level (WARNING logged) -- config session clear it first.
  • Introduce a single ConfigDomain descriptor + configDomains() and shared
    per-domain helpers so commit(), rollback() and config session diff
    handle the agent and BGP domains uniformly (private DiffDomain removed).
  • Make the agent skip-when-unchanged like BGP: a commit whose staged config
    equals what is already promoted is a true no-op (no git revision, no symlink
    churn, no reloadConfig()/bgpd restart). Change detection is semantic
    (compare the deserialized thrift structs), so formatting-only diffs don't
    count.
  • Consolidate config session clear onto a static stagedSessionFilePaths()
    and reuse ConfigSession::readStagedContent() in diff.
  • Make ConfigSession::saveConfig(service, level) generic over the service and
    reduce saveBgpConfig() to a thin wrapper.
  • Keep the heavy generated thrift headers out of ConfigSession.h: use the
    *_types_fwd.h forward-declaration headers, hold agentConfig_/bgpConfig_
    by std::unique_ptr, and drop the configLoaded_/bgpConfigLoaded_ bools
    (null == not loaded).

Test Plan

  • fboss/cli/fboss2/test/config:cmd_config_test passes (the config-session /
    commit / diff / BGP / clear unit tests cover the refactored paths); re-run in
    full after the action-level rename (871 tests).
  • //fboss/cli/... builds and tests pass on top of upstream/main.
  • Verified the agent no-op commit behaviour live on test switches.

@facebook-github-tools

Copy link
Copy Markdown

@hillol-nexthop has updated the pull request. You must reimport the pull request before landing.

@meta-codesync

meta-codesync Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

This pull request has been imported. If you are a Meta employee, you can view this in D114376130. (Because this pull request was imported automatically, there will not be any future comments.)

@facebook-github-tools

Copy link
Copy Markdown

@hillol-nexthop has updated the pull request. You must reimport the pull request before landing.

@facebook-github-tools

Copy link
Copy Markdown

@hillol-nexthop has updated the pull request. You must reimport the pull request before landing.

@facebook-github-tools

Copy link
Copy Markdown

@hillol-nexthop has updated the pull request. You must reimport the pull request before landing.

@induvsuresh induvsuresh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Overall lgtm but have some comments on whether BGP restart has been removed on config save

Comment thread fboss/cli/fboss2/cli_metadata.thrift Resolved
@facebook-github-tools

Copy link
Copy Markdown

@hillol-nexthop has updated the pull request. You must reimport the pull request before landing.

1 similar comment
@facebook-github-tools

Copy link
Copy Markdown

@hillol-nexthop has updated the pull request. You must reimport the pull request before landing.

@facebook-github-tools

Copy link
Copy Markdown

@hillol-nexthop has updated the pull request. You must reimport the pull request before landing.

@facebook-github-tools

Copy link
Copy Markdown

@hillol-nexthop has updated the pull request. You must reimport the pull request before landing.

Comment thread fboss/cli/fboss2/cli_metadata.thrift Outdated
Comment on lines +18 to +28
enum ConfigActionLevel {
HITLESS = 0, // Can be applied with reloadConfig() - default
AGENT_WARMBOOT = 1, // Requires agent warmboot restart
// Requires an agent warmboot restart (forwarding state retained).
AGENT_WARMBOOT = 1,
AGENT_COLDBOOT = 2, // Requires agent coldboot restart (clears ASIC state)
BGP_RESTART = 3, // Requires a restart of the bgpd (BGP++) service
// Plain service restart, for daemons with no warmboot or hitless-reload
// support (bgpd). Mechanically identical to a warmboot restart (plain
// systemctl restart-and-wait, no coldboot marker). Levels are only ever
// compared within one service, so 3 > 2 does NOT mean "more impactful
// than a coldboot".
SERVICE_RESTART = 3,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@hillol-nexthop This naming is a bit confusing and not very explicit especially AGENT_WARMBOOT and SERVICE_RESTART are basically the same thing?
Now with BGP config support, or potential future Qsfp config support, I think we need to revisit the meaning of these enums.
Correct me if I'm wrong, right now, you need ServiceType and ConfigActionLevel to decide what's the highest priority you need when handing session commit.
Can we consider to rename ConfigActionLevel to be:

enum ConfigActionLevel {
HITLESS = 0,  // Can be applied with reloadConfig() if the service supports
GRACEFUL_SERVICE_RESTART = 1, // Restart service gracefully (i.e agent warmboot or regular bgp restart)
DISRUPTIVE_SERVICE_RESTART = 2, // Restart service disruptively (i.e agent coldboot)
}

My main goal is to make this action level generic without worrying if someone do `session.commit(AGENT, SERVICE_RESTART);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@joseph5wu My initial implementation didn't even consider SERVICE_RESTART and I took the AGENT_WARMBOOT path for BGP which technically works. But I agree with Indu's comment that BGP doesn't support warmboot. So the code gives a false indication. GRACEFUL_SERVICE_RESTART is nothing but warmboot only and I don't think BGP implementation qualifies for this. Coldboot or DISRUPTIVE_SERVICE_RESTART involves marker file which again BGP doesn't use. So, BGP doesn't truly fit into any of these buckets.
My mental construct is:
Agent- {Warmboot, Coldboot}
BGP - {Restart}
Also with the new implementation the warmboot would be doing systemcl stop and start while with BGP just systemctl restart is fine.
So one way is to keep ConfigSession as the base class and implement derived classes for agents, BGP, qsfp And these restart specifics can be kept in the derived class implementation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

After discussed offline, we decided to go with these three enums:

  • hitless
  • service_restart
  • disruptive_service_restart

The goal is to keep the action level enum to be generic without being too specific for certain service's behavior, while in the code, we can base on SERVICE + ACTION_LEVEL to decide what kinda service restart needed in certain config.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated the code

@facebook-github-tools

Copy link
Copy Markdown

@hillol-nexthop has updated the pull request. You must reimport the pull request before landing.

@induvsuresh

Copy link
Copy Markdown
Contributor

@hillol-nexthop Looks like number of builds are failing in the PR - Build & Test fboss2 CLI, QSFP etc
is this intended? when I import the PR also I have CI failures

@facebook-github-tools

Copy link
Copy Markdown

@hillol-nexthop has updated the pull request. You must reimport the pull request before landing.

@hillol-nexthop

Copy link
Copy Markdown
Contributor Author

@hillol-nexthop Looks like number of builds are failing in the PR - Build & Test fboss2 CLI, QSFP etc is this intended? when I import the PR also I have CI failures

The failures are in getdeps stage where ftpmirror.gnu.org returned HTTP 502. I have rebased the PR and the CI is rerunning. Hopefully all turns green.

hillol-nexthop and others added 5 commits September 7, 2026 04:58
Follow-up cleanups to the BGP-aware config session infra (meta#1344):

- Collapse the BGP_RESTART action level into AGENT_WARMBOOT (bgpd has no hitless
  reload; its restart already runs the agent-warmboot code path).
- Introduce a single ConfigDomain descriptor + configDomains() and shared
  per-domain helpers so commit(), rollback() and `config session diff` handle
  the agent and BGP domains uniformly (private DiffDomain removed).
- Make the agent skip-when-unchanged like BGP: a commit whose staged config
  equals what is already promoted is a true no-op (no git revision, no symlink
  churn, no reloadConfig()/bgpd restart). Change detection is semantic (compare
  the deserialized thrift structs), so formatting-only diffs don't count.
- Consolidate `config session clear` onto a static stagedSessionFilePaths()
  and reuse ConfigSession::readStagedContent() in diff.
- Make ConfigSession::saveConfig(service, level) generic over the service and
  reduce saveBgpConfig() to a thin wrapper.
- Keep the heavy generated thrift headers out of ConfigSession.h: use the
  *_types_fwd.h forward-declaration headers, hold agentConfig_/bgpConfig_ by
  std::unique_ptr, and drop the configLoaded_/bgpConfigLoaded_ bools
  (null == not loaded).
- clang-tidy: use auto for the SimpleJSONSerializer template-cast results.

Built fboss2-dev + the config unit tests; config-session/commit/diff/BGP/clear
tests pass. Verified the agent no-op behaviour live on test switches.
…thInterface call

main renamed findFirstEthInterface() to getRandomInterfacePortName()
(virtual-management-port fix); convert the branch-added no-op-commit test
to the new helper. Drop the three includes ConfigSession.cpp no longer
uses directly (misc-include-cleaner runs as errors in CI).
bgpd has no warmboot, so recording AGENT_WARMBOOT for BGP config changes
was misleading in the enum, the session metadata, and the commit output
("bgpd (warmboot)"). Add a SERVICE_RESTART level used for BGP; it
short-circuits to the same plain restart-and-wait mechanism as a
warmboot restart (only AGENT_COLDBOOT writes the coldboot marker).
Commit output now prints bgpd without a boot-type suffix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review feedback: assert the no-op commit in scenario 2 returns an
empty commitSha, and for symmetry assert the real commits return a
non-empty one.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review feedback: AGENT_WARMBOOT and the bgpd-only SERVICE_RESTART were
the same thing, and the level names encoded one service's boot types.
Rename the levels so they describe impact only:

  HITLESS                      (unchanged)
  AGENT_WARMBOOT  -> SERVICE_RESTART
  AGENT_COLDBOOT  -> DISRUPTIVE_SERVICE_RESTART

and drop the interim SERVICE_RESTART = 3. What a level means for a given
service is decided from the (service, level) pair in
FbossServiceUtil::restartTypeName(): for the agent SERVICE_RESTART is a
warmboot and DISRUPTIVE_SERVICE_RESTART a coldboot (marker files); bgpd
has neither, so both are a plain restart. `config session commit` labels
each restarted service accordingly ("wedge_agent (warmboot)",
"bgpd (restart)").
@facebook-github-tools

Copy link
Copy Markdown

@hillol-nexthop has updated the pull request. You must reimport the pull request before landing.

Empty commit; previous run failed on a GNU mirror outage downloading binutils.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@facebook-github-tools

Copy link
Copy Markdown

@hillol-nexthop has updated the pull request. You must reimport the pull request before landing.

@meta-codesync meta-codesync Bot closed this in dde8684 Sep 11, 2026
@meta-codesync meta-codesync Bot added the Merged label Sep 11, 2026
@meta-codesync

meta-codesync Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

@joseph5wu merged this pull request in dde8684.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants