Skip to content

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

Open
hillol-nexthop wants to merge 4 commits into
facebook:mainfrom
nexthop-ai:bgp-session-unify
Open

[Nexthop][fboss2-dev] Unify agent/BGP config session + decouple ConfigSession header#1446
hillol-nexthop wants to merge 4 commits into
facebook: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.

  • 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).

Test Plan

  • fboss/cli/fboss2/test/config:cmd_config_test passes (the config-session /
    commit / diff / BGP / clear unit tests cover the refactored paths).
  • //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.

Follow-up cleanups to the BGP-aware config session infra (facebook#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.
Removed comments about the destructor definition in ConfigSession.h.
…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).
@facebook-github-tools

Copy link
Copy Markdown

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

A first `config protocol bgp ...` edit on a freshly imaged box discards
the running BGP config, leaving bgpd to crash-loop on an unset router_id.

The bgp++ RPM installs /etc/coop/bgpcpp.conf as a plain file (router_id
set), and the unit starts bgpd with --config /etc/coop/bgpcpp.conf.
ConfigSession, however, treated the *promoted* /etc/coop/bgpcpp/bgpcpp.conf
as the live read for BGP — a file that does not exist until the first
commit. So loadBgpConfig() fell through to schema defaults, and the commit
(which also replaces /etc/coop/bgpcpp.conf with a symlink into bgpcpp/)
promoted that near-empty config over the running one. This is what fails
as ConfigBgpGlobalTest.SetCountConfedsInAsPathLenTrue on a pristine box:
bgpd never binds its thrift port and the test throws Connection refused;
the next BGP test passes because teardown restarts bgpd.

The agent domain never had this bug: its systemPath is the symlink the
agent actually reads, so seeding works whether that path is still a plain
file or already the promoted symlink. BGP pointed it at the promoted file
instead. That inconsistency is the bug.

Change:
- ConfigDomain.systemPath for BGP -> getBgpSystemConfigLinkPath(). Safe
  because nothing writes via systemPath: writes use promotedPath, symlink
  creation uses symlinkPath, and systemPath is read only by
  'config session diff'.
- loadBgpConfig() seeds from staged edits -> the daemon's config path ->
  the promoted path as a backstop for a missing symlink.
- initializeGit() populates the promoted path from the daemon's config
  path before the baseline commit, so the first revision carries a BGP
  snapshot and a rollback to it cannot delete the running bgpcpp.conf.

(The companion ConfigBgpTestBase::systemBgpConfigPath() change is omitted
here: that fixture does not exist on this branch yet and the hunk rides
the BGP test PRs stacked above.)

Co-Authored-By: Claude Fable 5 <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.

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.

1 participant