Skip to content

[yang] Add BMC gNOI client certificate path model - #30103

Open
william8545 wants to merge 2 commits into
sonic-net:masterfrom
william8545:bmc-graceful-shutdown-restart
Open

william8545 wants to merge 2 commits into
sonic-net:masterfrom
william8545:bmc-graceful-shutdown-restart

Conversation

@william8545

Copy link
Copy Markdown
Contributor

Why I did it

The BMC daemon in sonic-platform-daemons#923 performs BMC-controlled graceful shutdown and restart of the switch host (HLD). It reaches the host over gNOI with mTLS and reads its client credential paths from the table BMC_GNOI|certs in the BMC's CONFIG_DB. That table has no YANG model yet, so it cannot be validated like the existing GNMI|certs server paths.

Work item tracking
  • Microsoft ADO (number only): N/A

How I did it

  • Add sonic-bmc-gnoi.yang: one optional singleton row BMC_GNOI|certs with the leaves ca_crt, client_crt and client_key. Each is an absolute path, visible inside the BMC's PMON container. The model defines no defaults, so an absent field does not materialize a row; the daemon falls back to /etc/sonic/bmc-link/{ca.crt,client.crt,client.key} for absent fields only.
  • Register the model in setup.py and add a BMC_GNOI entry to sample_config_db.json so the model is covered by the existing sample-config validation.
  • Add yang_model_pytests/test_bmc_gnoi.py: accepted path combinations, rejection of empty, bare-root, relative, templated and whitespace-containing paths, rejection of unknown rows or fields, and no leaf default.
  • Document the table in Configuration.md.

The image does not seed this table. Deployment installs the files and configures any non-default paths.

How to verify it

cd src/sonic-yang-models
pytest tests/yang_model_pytests/test_bmc_gnoi.py tests/yang_model_pytests/test_configdb_layout.py

The pytests need the python3-libyang this repository builds (libyang-python 3.1.0 with the src/libyang3-py3 patches), for example inside the sonic-slave container. The sonic-yang-mgmt validation test (test_validate_yang_models) loads every model together with sample_config_db.json and runs as part of the sonic-yang-mgmt build.

Which release branch to backport (provide reason below if selected)

  • 202305
  • 202311
  • 202405
  • 202411
  • 202505
  • 202511
  • 202512
  • 202605
  • 202608

Tracking issue/work item for backport/cherry-pick request (GitHub issue or Microsoft ADO): N/A
Failure type: other (feature)

Tested branch

  • master
  • 202305
  • 202311
  • 202405
  • 202411
  • 202505
  • 202511
  • 202512
  • 202605
  • 202608
  • N/A

Test result

  • master: tests/yang_model_pytests/ passed (1015 tests) and the sonic-yang-mgmt test_validate_yang_models and test_xlate_rev_xlate passed with this branch's models and sample config, run in a Debian bookworm container with libyang 3.12.2 and the libyang-python 3.1.0 built from src/libyang3-py3. setup.py build_py YANG completeness validation passed and pyang -Vf tree over all models reports nothing for the new model. No image build or hardware test was run for this YANG-only change; Azure CI runs the model tests in the sonic-yang-models and sonic-yang-mgmt builds.

Description for the changelog

Add the BMC_GNOI YANG model for the BMC daemon's gNOI client certificate paths.

Link to config_db schema for YANG module changes

https://github.com/william8545/sonic-buildimage/blob/bmc-graceful-shutdown-restart/src/sonic-yang-models/doc/Configuration.md#bmc_gnoi

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run Azure.sonic-buildimage

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

william8545 added a commit to william8545/sonic-platform-daemons that referenced this pull request Oct 15, 2026
#### Description

Implement BMC-side graceful shutdown and restart for the switch host.

- Send authenticated gNOI HALT and match RebootStatus to the running request before power removal.
- Serialize power actions: an identical action joins the in-flight request before any priority comparison, a higher-priority conflicting action preempts it, and other conflicting requests get BUSY responses.
- Record confirmed outcomes without replaying interrupted operations. A repeated shutdown is skipped only after a recorded power-off, an operation cancelled by daemon stop is recorded as ABANDONED, and the startup power-on is dropped when a power-removing request was admitted first.
- Read optional CA, client-certificate and private-key paths from CONFIG_DB `BMC_GNOI|certs`.
- Default the graceful timeout to 120 seconds while preserving configured values, including 0 for forced-only operation.

STATE_DB `HOST_STATE|switch-host` gains `op_request_id`, `op_trigger`, `op_result` and `op_reason`. Rack-manager command rows gain `request_id` for correlation.

#### Motivation and Context

Allow the host to stop services before BMC power removal while keeping critical-event handling and forced power operations available.

#### How Has This Been Tested?

- `git diff --check` passed.
- Added or updated unit coverage for gNOI failures, request correlation, timeouts, certificate paths, preemption, duplicate actions, power failures and daemon cleanup.
- The unit suite runs in Azure CI on this PR. A live-patch run of this daemon on a BMC and switch-host pair exercised graceful shutdown end to end, a critical event joining an in-flight graceful shutdown, startup with a pending power-off command and daemon stop during the handshake. No image build was run.

#### Additional Information (Optional)

This PR contains only the daemon-side changes. End-to-end graceful completion also needs [the switch-host `reboot -p` changes](sonic-net/sonic-utilities#4906), [the host-services HALT changes](sonic-net/sonic-host-services#449) and deployment-provisioned mTLS credentials. The YANG model for the optional `BMC_GNOI|certs` table is in [sonic-buildimage#30103](sonic-net/sonic-buildimage#30103).

Each operation runs on its own worker thread, with at most one worker alive at a time, so the daemon keeps processing events and critical actions during the graceful wait; daemon stop joins the worker for at most 5 seconds. Each thread uses its own database connections. The rack-manager telemetry handler added in sonic-net#880 runs on the event thread's subscription list.

A request that conflicts with the in-flight operation is refused as BUSY and is not queued or retried. The refusal is reported in the rack-manager command row and the event log, while `HOST_STATE|switch-host` keeps the record of the in-flight operation. CLI admin-status writes are deduplicated per value, so an `admin_status=up` written while a shutdown is in flight is not acted on: it is a no-op while the host is still online and is refused as BUSY once it is off. To power on afterwards, run `config chassis modules shutdown SWITCH-HOST` and then `startup` again.

Signed-off-by: William Tsai <willtsai@nvidia.com>
#### Why I did it

The BMC daemon in [sonic-platform-daemons#923](sonic-net/sonic-platform-daemons#923) performs BMC-controlled graceful shutdown and restart of the switch host ([HLD](sonic-net/SONiC#2500)). It reaches the host over gNOI with mTLS and reads its client credential paths from the table `BMC_GNOI|certs` in the BMC's CONFIG_DB. That table has no YANG model yet, so it cannot be validated like the existing `GNMI|certs` server paths.

##### Work item tracking
- Microsoft ADO **(number only)**: N/A

#### How I did it

- Add `sonic-bmc-gnoi.yang`: one optional singleton row `BMC_GNOI|certs` with the leaves `ca_crt`, `client_crt` and `client_key`. Each is an absolute path, visible inside the BMC's PMON container. The model defines no defaults, so an absent field does not materialize a row; the daemon falls back to `/etc/sonic/bmc-link/{ca.crt,client.crt,client.key}` for absent fields only.
- Register the model in `setup.py` and add a `BMC_GNOI` entry to `sample_config_db.json` so the model is covered by the existing sample-config validation.
- Add `yang_model_pytests/test_bmc_gnoi.py`: accepted path combinations, rejection of empty, bare-root, relative, templated and whitespace-containing paths, rejection of unknown rows or fields, and no leaf default.
- Document the table in `Configuration.md`.

The image does not seed this table. Deployment installs the files and configures any non-default paths.

#### How to verify it

```
cd src/sonic-yang-models
pytest tests/yang_model_pytests/test_bmc_gnoi.py tests/yang_model_pytests/test_configdb_layout.py
```

The pytests need the `python3-libyang` this repository builds (libyang-python 3.1.0 with the `src/libyang3-py3` patches), for example inside the sonic-slave container. The sonic-yang-mgmt validation test (`test_validate_yang_models`) loads every model together with `sample_config_db.json` and runs as part of the sonic-yang-mgmt build.

#### Which release branch to backport (provide reason below if selected)

- [ ] 202305
- [ ] 202311
- [ ] 202405
- [ ] 202411
- [ ] 202505
- [ ] 202511
- [ ] 202512
- [ ] 202605
- [ ] 202608

Tracking issue/work item for backport/cherry-pick request (GitHub issue or Microsoft ADO): N/A
Failure type: other (feature)

#### Tested branch

- [x] master
- [ ] 202305
- [ ] 202311
- [ ] 202405
- [ ] 202411
- [ ] 202505
- [ ] 202511
- [ ] 202512
- [ ] 202605
- [ ] 202608
- [ ] N/A

#### Test result

- master: `tests/yang_model_pytests/` passed (1015 tests) and the sonic-yang-mgmt `test_validate_yang_models` and `test_xlate_rev_xlate` passed with this branch's models and sample config, run in a Debian bookworm container with libyang 3.12.2 and the libyang-python 3.1.0 built from `src/libyang3-py3`. `setup.py build_py` YANG completeness validation passed and `pyang -Vf tree` over all models reports nothing for the new model. No image build or hardware test was run for this YANG-only change; Azure CI runs the model tests in the sonic-yang-models and sonic-yang-mgmt builds.

#### Description for the changelog

Add the `BMC_GNOI` YANG model for the BMC daemon's gNOI client certificate paths.

#### Link to config_db schema for YANG module changes

https://github.com/william8545/sonic-buildimage/blob/bmc-graceful-shutdown-restart/src/sonic-yang-models/doc/Configuration.md#bmc_gnoi

Signed-off-by: William Tsai <willtsai@nvidia.com>
@william8545
william8545 force-pushed the bmc-graceful-shutdown-restart branch from 7f7ea85 to b86aa5b Compare October 15, 2026 22:37
william8545 added a commit to william8545/SONiC that referenced this pull request Oct 15, 2026
## Summary

Align the BMC graceful shutdown/restart HLD merged in sonic-net#2500 with the implementation.

Only the existing HLD is changed; its section structure and main flows are retained.

## Differences from the merged HLD

| Area | Updated design |
| --- | --- |
| Eligibility | Use existing BMC/switch-host identity. Remove the `bmc_pairing` opt-in and old/mixed-image compatibility promise. |
| Provisioning | Deployment owns credentials, gNMI authorization and CACL. BMC client paths use optional `BMC_GNOI\|certs`; host server paths use existing `GNMI\|certs`. No image-side DB seeding. |
| Timing | Default BMC timeout 120 s, explicit 0 preserved, no CLI upper bound. Host timeout defaults to 60 s without DPU fallback; watchdog 180 s; restart pause 10 s. |
| Host safeguards | Document watchdog readback, the skipped platform pre-reboot hook and firmware auto-update handler, the checked host-partition flush, and immediate propagation of pre-check failures, including the narrow shared-path fixes. |
| Operation handling | Align same-action JOIN ahead of priority displacement, preemption ownership, the startup power-on yielding to an admitted power removal, the repeated-shutdown skip after a recorded power-off, ABANDONED on daemon stop and no automatic power-call retry. Distinguish platform `ONLINE` from OS/management readiness. |

The tagged HALT/RebootStatus protocol, vendor teardown branches and deployment qualification requirements remain. This PR does not claim production security approval or introduce runtime changes.

## Validation

- Compared with the implementation proposed in sonic-net/sonic-platform-daemons#923, sonic-net/sonic-host-services#449, sonic-net/sonic-utilities#4906 and sonic-net/sonic-buildimage#30103.
- Checked document structure, link targets and whitespace.
- Documentation only: no build or device test.

Signed-off-by: William Tsai <willtsai@nvidia.com>
@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run Azure.sonic-buildimage

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@william8545

Copy link
Copy Markdown
Contributor Author

/azpw retry

@azure-pipelines-wrapper

Copy link
Copy Markdown

You are not authorized to retry Azure Pipelines jobs for this repository.

@william8545

Copy link
Copy Markdown
Contributor Author

/azpw run

@azure-pipelines-wrapper

Copy link
Copy Markdown

You are not authorized to retry Azure Pipelines jobs for this repository.

Empty commit. The previous run of this unchanged YANG-only change failed in
one kvmtest leg (t1-lag-vpp) while the builds and the other kvmtest legs
passed; the author cannot re-run the pipeline on this repository.

Signed-off-by: William Tsai <willtsai@nvidia.com>
@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run Azure.sonic-buildimage

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

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