Skip to content

Merging latest upstream sonic-gnmi master into kubesonic - #229

Merged
Sreevanich16 merged 14 commits into
Azure:kubesonicfrom
Sreevanich16:merge-upstream-into-kubesonic
Jul 16, 2026
Merged

Merging latest upstream sonic-gnmi master into kubesonic#229
Sreevanich16 merged 14 commits into
Azure:kubesonicfrom
Sreevanich16:merge-upstream-into-kubesonic

Conversation

@Sreevanich16

@Sreevanich16 Sreevanich16 commented Jul 15, 2026

Copy link
Copy Markdown

Why I did it

To bring latest public sonic-gnmi master changes into Azure/sonic-gnmi.msft:kubesonic

How I did it

Merged all the latest commits from public gnmi repo into sonic-gnmi.msft and resolved merge conflicts in the below files manually.
.github/workflows/codeql-analysis.yml
azure-pipelines.yml
go.mod
go.sum
sonic_data_client/virtual_db.go
telemetry/telemetry_test.go

How to verify it

Build succeeded with the latest commits.

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

  • 201811
  • 201911
  • 202006
  • 202012
  • 202106
  • 202111

Description for the changelog

Link to config_db schema for YANG module changes

A picture of a cute animal (not mandatory but encouraged)

Why I did it
sonic-buildimage no longer builds the libyang1 debs (libyang_1.0.73, libyang-cpp, python3-yang); it now builds only libyang3. The sonic-gnmi CI downloads and installs libyang debs from the sonic-buildimage.common_libs build artifact, and the libyang1-versioned download patterns no longer match any produced artifact, which would break the dependency-install step.

How I did it
Updated the libyang download filter list in .azure/templates/install-dependencies.yml:

Removed target/debs/trixie/libyang_1.0*.deb (the v1 runtime library); the libyang3 runtime is already covered by the existing target/debs/trixie/libyang3_*.deb pattern.
Replaced target/debs/trixie/libyang-*_1.0*.deb (which matched the now-removed libyang-cpp and the v1 libyang-dev) with the versionless target/debs/trixie/libyang-dev_*.deb (now v3), dropping libyang-cpp entirely.
All patterns are versionless globs. The install step already uses a generic find ... -name '*.deb' invocation, so it installs whatever was downloaded and needed no change.

Left unchanged:

doc/telemetry-dev-env/Dockerfile builds libyang 1.0.184 from CESNET source for the developer environment; it is not a sonic-buildimage build asset.
Makefile comments referencing libyang memory leaks are descriptive only and unrelated to the deb migration.
How to verify it
Run the sonic-gnmi Azure CI; the "Download libyang and libnl from common_libs" step resolves the new versionless libyang3 patterns, and the "Install libyang and libnl debs" step installs them successfully.
Confirm no remaining libyang1 deb references or hardcoded versions: grep -rnI 'libyang_1.0\|libyang-.*_1.0' .azure/

Signed-off-by: Brad House <bhouse@nexthop.ai>
* [gnoi] file: implement Stat in-house using /mnt/host

Replace the DBus-backed File.Stat handler with a pure-Go implementation
that reads metadata directly via os.Stat / os.ReadDir on the host
filesystem, bind-mounted into the gnmi container at /mnt/host. The
existing translatePathForContainer helper (already used by Put,
TransferToRemote, and Remove) handles the host-vs-container path
prefix.

Per the gNOI proto ("Stat will list files at the provided path") the
handler now supports both cases:

  - regular file -> single StatInfo for that file
  - directory   -> one StatInfo per immediate child (non-recursive)

Permissions are encoded octal-as-decimal as the proto requires (e.g.
0644 -> Permissions=644). The umask field is reported as a constant
0022 (defaultUmask); per-file umask is not derivable from os.Stat and
the previous DBus implementation also returned a process umask, so
behavior is unchanged for callers that don't rely on the exact value.

Tests:
  - 8 new pure-Go unit tests in pkg/gnoi/file/stat_test.go covering
    nil/empty/relative path, NotFound, regular file, directory listing
    (incl. subdirs), empty directory, and the octal-as-decimal
    permissions encoding.
  - Existing gnmi_server Stat tests rewritten to drive the new handler
    (no DBus mock); removes the dependency on
    sonic_service_client.GetFileStat for Stat.
  - Local pure-test run: 636 tests pass (was 628; +8 new).
  - Live verified end-to-end on a sonic-mgmt KVM testbed against the
    gnmi container's /var/run/gnmi/gnmi.sock UDS for /tmp/, /etc/,
    /var/log/, and /host/reboot-cause; see PR description for the full
    test matrix and a reproducible grpcurl example.
Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* [gnoi] file: trim gnmi_server Stat tests to wiring-only

Behavior coverage for File.Stat lives in pkg/gnoi/file/stat_test.go
(NotFound, regular file, directory listing, empty directory, the
octal-as-decimal permissions encoding, nil/empty/relative request
validation). Re-asserting all of that through the gnmi_server gRPC
client just duplicated the pure-package coverage and forced fragile
/mnt/host skip guards into the gnmi_server suite.

Reduce gnmi_server's TestGnoiFile Stat coverage to two minimal
sub-tests that only verify server wiring:

  - the authenticate hook runs before the handler (Unauthenticated
    surfaces as gRPC Unauthenticated)
  - an authenticated request reaches HandleStat and a handler-level
    error (empty path -> InvalidArgument) propagates out as the
    matching gRPC status code

Drop the FileStatSuccess and FileStatFailure sub-tests from
gnmi_server/server_test.go for the same reason; nothing they
asserted was specific to the gnmi_server stack.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* [gnoi] file: address copilot review on Stat handler

Three fixes to the new HandleStat from PR review:

1. Map os.ReadDir NotExist to NotFound. The directory may be removed
   between the os.Stat above the dir branch and the ReadDir inside it;
   that race used to surface as Internal, hiding a benign condition
   behind a server-error code.

2. Reject /mnt/host-prefixed input paths with InvalidArgument.
   translatePathForContainer unconditionally prepends /mnt/host when
   that directory exists, so a client that already sent a
   container-internal path would otherwise hit
   /mnt/host/mnt/host/... and get a confusing NotFound. Tell the
   client to drop the prefix instead.

3. Replace the test-level skipIfMntHost helper with a statTestRoot
   helper that creates the fixture under the *physical* root
   (/mnt/host/tmp/... when /mnt/host is present) while feeding the
   matching *logical* path to HandleStat. This restores Stat test
   coverage on containerized hosts where /mnt/host exists. Also
   adds TestHandleStat_RejectsMntHostPrefix to lock in the new
   InvalidArgument path.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* [gnoi] file: drop unused test imports

Integration build (Test stage on the ADO pipeline) failed with:
  gnmi_server/gnoi_file_test.go:8:2: "path/filepath" imported and not used
  gnmi_server/server_test.go:68:2: "github.com/openconfig/gnoi/file" imported as gnoi_file_pb and not used

Pure tests didn't catch this because they don't compile gnmi_server. Remove
the now-orphaned imports left over after the test trim in 8b66d3a.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* [gnoi] file: cover HandleStat error branches via fs seam

Diff coverage on the PR was 75% (43/57), below the 80% threshold. The
uncovered lines were all error paths in HandleStat that the test
container can't reach with real os.* calls: as root on tmpfs we don't
hit PermissionDenied (DAC bypassed), and we can't race a TOCTOU between
os.Stat and os.ReadDir.

Avoid gomonkey by introducing a tiny package-internal seam:

  var (
      fsStat    = os.Stat
      fsReadDir = os.ReadDir
  )

HandleStat calls those instead of os.Stat / os.ReadDir directly. Tests
swap them in for the duration of a single test (see withFsStat /
withFsReadDir helpers in stat_test.go) to inject specific errors:

  - TestHandleStat_StatPermissionDenied   (line 660-661)
  - TestHandleStat_StatGenericError       (line 663)
  - TestHandleStat_ReadDirNotExistRace    (line 683-684)
  - TestHandleStat_ReadDirPermissionDenied(line 686-687)
  - TestHandleStat_ReadDirGenericError    (line 689)

Production behavior is unchanged: fsStat and fsReadDir keep their os.*
defaults, the original os.Is{NotExist,Permission} mapping logic is the
same, and no new package is introduced.

HandleStat statement coverage: ~78% -> 89.1%; diff coverage clears the
80% gate.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* [gnoi] file: gofmt stat_test.go

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

---------

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>
nsenter does not inherit the host PATH when executing commands from
within the container. Use /usr/local/bin/sonic-installer as the full
path to ensure the command is found.

Also use 'binary-version' subcommand instead of deprecated
'binary_version' which fails on newer sonic-installer versions.

Signed-off-by: Chandra Shekar (WIPRO LIMITED) <v-cshekar@microsoft.com>
* [gnoi] file: implement Get in-house using /mnt/host

Replace the Unimplemented stub for File.Get with a pure-Go handler
that streams a host file directly to the caller via the existing
/mnt/host bind mount, the same translation pattern File.Put,
File.TransferToRemote, File.Remove, and (after #697) File.Stat
already use. No D-Bus hop, no host service.

Per the gNOI proto: "Get reads and streams the contents of a file
from the target. The file is streamed by sequential messages, each
containing up to 64KB of data. A final message is sent prior to
closing the stream that contains the hash of the data sent."

HandleGet implements that:
  - validate request (non-nil, absolute path, not /mnt/host-prefixed)
  - reject directories and non-regular files with FailedPrecondition
  - cap file size at the package-wide maxFileSize (4 GiB)
  - stream 64 KiB chunks while updating a running MD5
  - send a final HashType{MD5, sum} message
  - check stream context between chunks so cancelled clients abort
    promptly

MD5 matches the convention HandlePut and HandleTransferToRemote
already use in this package; it's integrity-only, not security
critical.

Tests:
  - pkg/gnoi/file/get_test.go covers nil request, empty path,
    relative path, /mnt/host prefix rejection, NotFound, directory
    rejection, empty file (just the hash), small file (single chunk
    + hash), 200 KiB file (forces 4 chunks + hash, validates payload
    and MD5 round-trip), Send error propagation, and cancelled
    context. Uses a fake File_GetServer that copies Contents on Send
    to mirror real gRPC's synchronous-marshal contract.
  - gnmi_server/gnoi_file_test.go: replace the old
    Get_Fails_With_Unimplemented_Error sub-test with a
    Get_Delegates_To_Handler smoke test that confirms an
    authenticated request reaches HandleGet and a handler-level
    error (empty remote_file -> InvalidArgument) propagates out
    through the server stack as the matching gRPC status code.
    Auth-error sub-test kept as-is.
  - Local pure suite: 628 -> 639 (+11). Live verified end-to-end on
    a sonic-mgmt KVM testbed via grpcurl over /var/run/gnmi/gnmi.sock
    for /tmp/, /etc/, and /host/ paths; see PR description.
Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* [gnoi] file: make hostRoot/maxFileSize injectable, cover Get error branches

Diff coverage on the original PR was 78%, below the 80% threshold. The
uncovered lines were all error paths in HandleGet that os.Stat / os.Open
basically never trigger on the test container (root-bypasses-mode-bits,
no >4 GiB files, MD5 never errors, etc.).

Rather than reach for gomonkey, expose two knobs that already wanted to
be injectable for cleaner test setup:

  - hostRoot (was a hardcoded "/mnt/host" inside translatePathForContainer)
    is now a package var. Tests can point it at a t.TempDir() and build
    real fixtures (regular files, fifos, oversize sparse files) without
    needing /mnt/host on the host or relying on dual-path probing. The
    helper useTempHostRoot(t) wraps the swap+restore.

  - maxFileSize is now a var so tests can lower it to 16 bytes and
    exercise the oversize branch with a 32-byte file instead of a 4 GiB
    one.

Production behavior is unchanged: hostRoot defaults to "/mnt/host" and
maxFileSize to 4 GiB.

Three new tests cover the previously-missed branches:

  - TestHandleGet_NotRegularFile  (line 625, syscall.Mkfifo)
  - TestHandleGet_OversizeFile    (line 628, lowered maxFileSize)
  - TestHandleGet_HashSendError   (line 674, fakeGetServer.failOnHash)

Existing tests are migrated to the new helper, removing the
/mnt/host-detection fallback in get_test.go.

HandleGet line coverage: 64% -> 84%; diff coverage clears the 80% gate.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

---------

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>
…692)

* doc: design for gNOI ORAS Pull service

Draft RFC for a new sonic.gnoi.oras.v1.Oras service that lets an
orchestrator instruct a switch to pull an OCI/ORAS artifact from a
registry into local staging, decoupled from install.

Tracks ADO Feature #37984064.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* doc: correct framing of SONiC TransferToRemote

SONiC's TransferToRemote actually performs a download (HTTP GET into
local_path), not an upload as upstream openconfig defines. Update §1 to
describe the real current state and enumerate the concrete limitations
that block its use for ACR/ORAS.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* proto: add sonic.gnoi.oras.v1.Oras service definition

PoC subset of the ORAS Pull design (doc/oras-pull-design.md): a single
streaming Pull RPC with anonymous + basic auth and an optional
http_proxy field. List/Delete and richer features are deferred.

Generated oras.pb.go is checked in following the existing precedent
(proto/sonic.pb.go, proto/gnoi/sonic_debug.pb.go). Makefile wires the
new binding into PROTO_GO_BINDINGS so make can regenerate it.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* pkg/gnoi/oras: implement Pull RPC

Streaming server implementation of sonic.gnoi.oras.v1.Oras.Pull:

  * Resolves manifest by tag or digest against an OCI registry.
  * Requires single-layer artifacts (PoC scope per the design doc;
    SONiC OS images are single layer).
  * Stages the layer into a temp dir next to local_path and renames
    into place on success, so a failed pull never leaves a partial
    file at local_path.
  * Emits PullStarted once the manifest is resolved, PullProgress at
    most once per second, and a final PullResult with elapsed time
    and per-layer digest.
  * Reuses the file-server path allowlist (/tmp, /var/tmp, /host).
  * Supports anonymous and basic auth (ACR admin user); workload
    identity and bearer modes are stubbed out for v1.
  * http_proxy field plumbed into the HTTP transport so testbeds
    where the registry is not reachable via the default route (e.g.
    sonic-vs vlabs behind a host tinyproxy) can still pull.
  * Best-effort registry-error to gRPC status mapping.

Adds oras.land/oras-go/v2 v2.6.0 and github.com/opencontainers/image-spec
v1.1.1 to go.mod.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* gnmi_server: register sonic.gnoi.oras.v1.Oras

Add OrasServer wrapper and wire it into registerAllServices behind the
existing EnableTranslibWrite || EnableNativeWrite gate, alongside the
other gNOI services. Pull authenticates the caller and then delegates
to pkg/gnoi/oras.HandlePull.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* gnmi_server: register Oras unconditionally

Drop the EnableTranslibWrite/EnableNativeWrite gate for sonic.gnoi.oras.v1.Oras.
The other services inside that gate are there because gNMI write paths
(translib / native YANG) should not be exposed unless the operator opted in
to writes. Oras Pull does not touch any YANG datastore — it writes only into
an allowlisted staging area inside the gnmi container — so the gate is not
meaningful here. Keep the service available on every build, mirroring the
unconditional registration of system / factory_reset.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* pkg/gnoi/oras: add unit tests, split HandlePull for testability

Introduce handlePullWithRepo as a seam so tests can drive the pull loop
against an httptest-backed fake registry (PlainHTTP) without reaching
the real network. HandlePull keeps the same public signature, validates
the request, constructs the repository, then delegates.

New tests cover:
  - validatePullRequest (12 cases)
  - validateLocalPath (allowlist + traversal)
  - pullReference (tag vs digest precedence)
  - pickSingleLayer (0/1/2 layers, malformed JSON)
  - mapRegistryError (401/host/timeout/404/ENOSPC/default)
  - countingReader, copyAndRemove, jsonUnmarshalStrict
  - newRepository wires basic-auth credentials + leaves Credential nil
    for anonymous; rejects invalid registry refs
  - HandlePull happy path and auth-failure path against a fake registry

Package coverage now 81.8%.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* pkg/gnoi/oras: gofmt oras_test.go

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* pure.mk: register pkg/gnoi/oras as a pure package

pkg/gnoi/oras has no CGO or SONiC dependencies, so its tests can run
in the pure-test stage. Registering it here makes the pipeline pick up
the unit tests and include them in the diff-coverage gate.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* pkg/gnoi/oras: expand error-branch test coverage

Add tests for HandlePull wrapper (E2E + bad registry ref), multi-layer
manifest rejection, MkdirTemp failure, blob fetch 500, Send error on
PullStarted, and copyAndRemove dst-open error. Lifts statement coverage
from 81.8% to 89.9% so the pipeline diff-coverage gate (>=80% lines)
clears with comfortable margin.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* pkg/gnoi/oras: address review feedback

- Serialize stream.Send through a safeStream mutex; close progressDone
  before final Send (and wait for the progress goroutine to exit) so the
  progress goroutine can never race with PullResult.
- Restrict os.Rename copy-and-delete fallback to EXDEV only; surface
  permission / target-is-dir / etc. errors as-is instead of silently
  masking them.
- Replace substring-based mapRegistryError with errors.As inspection of
  errcode.ErrorResponse, errdef.ErrNotFound, net.OpError/DNSError,
  net.Error.Timeout(), and syscall.ECONNREFUSED / ENOSPC. Adds
  PermissionDenied for 403.
- validateLocalPath: walk path components for literal '..' segments
  instead of strings.Contains, which over-rejected names like 'a..b'.
- Drop the dead '_ = oras.Copy' line and the oras-go top-level import.
- Rename jsonUnmarshalStrict -> parseManifest; comment matches behavior.
- proto: redact registry hostname example; move PoC-subset scope notes
  from the file-level comment (which protoc-gen-go places in front of
  the DO NOT EDIT marker) to the Oras service comment; regen pb.go.
- Tests: switch hard-coded /tmp/oras-test-<pid>.bin paths to a per-test
  MkdirTemp helper under /tmp; rename proto_clone -> protoClone; add
  TestIsCrossDeviceError; rework TestMapRegistryError to use typed
  errors.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* pkg/gnoi/oras: drop http_proxy from PullRequest, lean on env vars

http_proxy on the wire mixes ops policy into the RPC contract. Go's
http.DefaultTransport already honors the standard HTTP_PROXY / HTTPS_PROXY
/ NO_PROXY env vars via http.ProxyFromEnvironment, and lab testbeds can
inject those on the gnmi process (e.g. via /usr/bin/gnmi-native.sh).
Production switches with a default route to the registry need no
configuration.

Also trims the design doc's PullRequest example: removes media_type_filter,
source_address, source_vrf, skip_if_exists, expected_manifest_digest — all
speculative v2+ knobs that don't belong in the first cut. Lists them in a
'deliberately deferred' section so the rationale is preserved.

Regenerates oras.pb.go to drop field Azure#7.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* pkg/hostfs: add shared host-path validate + container translate helpers

New /tmp/, /var/tmp/, /host/ allowlist + /mnt/host bind-mount translation
lives in pkg/hostfs. pkg/gnoi/oras switches over so its writes land on the
host filesystem (sonic-installer reads from the host /tmp, not the
container's tmpfs).

internal/diskspace and pkg/gnoi/file still have their own private copies
of this logic; migrating them is a follow-up to keep this change focused.

Also picks up an existing go.mod entry (opencontainers/go-digest is used
directly by the oras tests; promote it from indirect).

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

* doc/oras-pull-design: add mermaid sequence for end-to-end Pull flow

Documents how HandlePull drives oras-go through Resolve → Fetch →
file.Store, where progress comes from (countingReader + 1s ticker), and
why the staging dir is created next to the destination (same-fs rename).
Captures hostfs.Translate as the container→host path seam.

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>

---------

Signed-off-by: Dawei Huang <daweihuang@microsoft.com>
CodeQL action v2 is unsupported and v3 is deprecated. Bump
github/codeql-action init/analyze from v2.1.29 to v4 so scans run on
the current CodeQL engine and catch more types of issues, matching the
newer scans that surfaced #694. Also bump the supporting
actions/checkout steps from v3 to v4 since v4 runs on Node 24.

Fixes #695

Signed-off-by: Dawei Huang <dwhuang9@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Re-lands sonic-net/sonic-gnmi#652 (reverted in #673).

The original was reverted due to a coverage gap in cert auth; that issue
was separately fixed (TestCertAuthDisabledWhenNoCaCert added in #673 stays).

Changes:
- gnmi_server/server.go: add BindAddress to Config struct; use it in
  net.Listen() when binding the TCP listener (VRF path unchanged)
- telemetry/telemetry.go: add --bind_address flag; enforce that --noTLS
  requires a loopback address to prevent cleartext gRPC exposure
- telemetry/telemetry_test.go: add --bind_address 127.0.0.1 to all
  existing --noTLS test cases; add TestNoTLSRequiresLoopbackAddress

Signed-off-by: xq9mend <xq9mend@users.noreply.github.com>
Co-authored-by: xq9mend <xq9mend@users.noreply.github.com>
--bind_address is optional hardening; operators may legitimately use
--noTLS without it in isolated networks, containers, or lab setups.
Remove the enforcement that required --bind_address to be a loopback
address when --noTLS is active, and drop the test that covered it.

The --bind_address flag itself is retained -- operators can still
restrict the listener to localhost when desired.

Signed-off-by: xq9mend <xq9mend@users.noreply.github.com>
Co-authored-by: xq9mend <xq9mend@users.noreply.github.com>
* Fix CHASSIS_STATE_DB errors on non-chassis platforms

Below error logs that appear across gnmi restarts:
ERR gnmi#telemetry: :- getDbInfo: Failed to find CHASSIS_STATE_DB database in : key
ERR gnmi#dialout_client_cli: :- getDbInfo: Failed to find CHASSIS_STATE_DB database in : key

These logs cause teardown errors in sonic-mgmt tests

Signed-off-by: Ravi Minnikanti <rminnikanti@marvell.com>

* Added UT for new logic in initRedisDbClients() for code coverage

Signed-off-by: Ravi Minnikanti <rminnikanti@marvell.com>

* Fixed review comments

1. Used sync.Once to do one-time detection of CHASSIS_STATE_DB
   present or not
2. Used constant for CHASSIS_STATE_DB
3. Replaced map[string]bool with map[string]struct{}.

Signed-off-by: Ravi Minnikanti <rminnikanti@marvell.com>

* Fix review comments

1. Removed Sync.Once logic
2. Used slices.Contains which is available in Go 1.24

Signed-off-by: Ravi Minnikanti <rminnikanti@marvell.com>

---------

Signed-off-by: Ravi Minnikanti <rminnikanti@marvell.com>
* Implement OnceRun for MixedDbClient and DbClient Subscribe ONCE

Subscribe ONCE mode (gnmi_cli -query_type=once) was broken because
OnceRun() in both MixedDbClient and DbClient were no-op stubs that
returned immediately without sending any data to the client.

Implement OnceRun to perform a single-shot data fetch from Redis,
enqueue the results to the priority queue, and send a sync_response
to signal completion. This follows the same pattern as PollRun but
executes only one iteration.

Changes:
- sonic_data_client/mixed_db_client.go: Implement MixedDbClient.OnceRun()
- sonic_data_client/db_client.go: Implement DbClient.OnceRun()
- test/utils.py: Add gnmi_subscribe_once() and gnmi_subscribe_once_multiple()
- test/test_gnmi_configdb.py: Add TestGNMISubscribeOnce with 7 test cases

Without this fix, any gNMI client using Subscribe ONCE hangs until
timeout (rc=124) because the server never sends data or sync_response.

Signed-off-by: Ashwin Srinivasan <asrinivasan@juniper.net>
@azure-pipelines

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

Comment thread pkg/gnoi/oras/oras.go Dismissed
@Sreevanich16 Sreevanich16 changed the title Merge public gnmi upstream into kubesonic Merging latest upstream sonic-gnmi master into kubesonic Jul 15, 2026
@Sreevanich16

Copy link
Copy Markdown
Author

/azp run

@azure-pipelines

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

@Sreevanich16

Copy link
Copy Markdown
Author

/azp run

@azure-pipelines

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

@Sreevanich16

Copy link
Copy Markdown
Author

/azp run

@azure-pipelines

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM

@Sreevanich16
Sreevanich16 merged commit a6002d1 into Azure:kubesonic Jul 16, 2026
10 checks passed
@Sreevanich16 Sreevanich16 mentioned this pull request Aug 28, 2026
6 tasks
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.

10 participants