Skip to content

[gNOI] Added initial implementation of gNOI.OS Install RPC.#429

Draft
kanchanavelusamy wants to merge 1 commit intosonic-net:masterfrom
kanchanavelusamy:gnoi_os_fe_pr1
Draft

[gNOI] Added initial implementation of gNOI.OS Install RPC.#429
kanchanavelusamy wants to merge 1 commit intosonic-net:masterfrom
kanchanavelusamy:gnoi_os_fe_pr1

Conversation

@kanchanavelusamy
Copy link
Contributor

@kanchanavelusamy kanchanavelusamy commented Jun 23, 2025

Client Implementation [https://github.com/kanchanavelusamy/pull/3]
Dependent Backend PR: [https://github.com/sonic-net/sonic-host-services/pull/270]

[UMF] gNOI OS Service - Test Results
Manual CLI Testing

Verify RPC

admin@sonic:~$ docker exec -it gnmi gnoi_client -target 127.0.0.1:8080 -logtostderr -notls -module OS -rpc Verify 
OS Verify
{"version":"SONiC-OS-master.0-4b447731e"}
admin@sonic:~$ 

Activate RPC

admin@sonic:~$ docker exec -it gnmi gnoi_client -target 127.0.0.1:8080 -logtostderr -notls -module OS -rpc Activate -jsonin '{ "version": "SONiC-OS-master.0-4b447731e", "no_reboot": true }'
OS Activate
{"Response":{"ActivateOk":{}}}
admin@sonic:~$ 

Install RPC

admin@sonic:~$ docker exec gnmi gnoi_client -target 127.0.0.1:8080 -notls -module OS -rpc Install -jsonin '{"transferRequest": {"version": "SONiC-OS-master.0-4b447731e", "standby_supervisor": false}}' --input_file=SONiC-OS.tar.gz
OS Install
Error receiving stream: rpc error: code = Unimplemented desc = OS Install not supported
admin@sonic:~$

gnmi.log for reference.

UT Results:

2025-09-05T13:22:09.2630939Z === RUN   TestOSServer
2025-09-05T13:22:10.7093953Z === RUN   TestOSServer/OSInstallFailsIfTransferRequestIsMissingVersion
2025-09-05T13:22:10.7303078Z E0905 13:22:10.729785   20907 gnoi_os.go:40] processTransferReq: TransferRequest must contain a valid OS version.
2025-09-05T13:22:10.7323018Z === RUN   TestOSServer/OSInstallFailsForConcurrentOperations
2025-09-05T13:22:10.7773188Z     gnoi_os_test.go:150: InstallError=rpc error: code = Aborted desc = Concurrent Install RPCs are not allowed.
2025-09-05T13:22:10.7774886Z     gnoi_os_test.go:153: Client continue with the existing stream
2025-09-05T13:22:10.7794301Z === RUN   TestOSServer/OSInstallFailsIfWrongMessageIsSent
2025-09-05T13:22:10.8028866Z E0905 13:22:10.801652   20907 gnoi_os.go:305] Install: TransferRequest is nil
2025-09-05T13:22:10.8032866Z === RUN   TestOSServer/OSInstallAbortedImmediately
2025-09-05T13:22:10.8249228Z E0905 13:22:10.824370   20907 gnoi_os.go:296] Install: Received EOF while receiving TransferRequest!
2025-09-05T13:22:10.8258844Z === RUN   TestOSServer/OSInstallFailsIfImageExistsWhenTransferBegins
2025-09-05T13:22:10.8489830Z E0905 13:22:10.848333   20907 gnoi_os.go:362] Install: Image /tmp/os1.1 already exists. Aborting TransferContent.
2025-09-05T13:22:10.8502198Z === RUN   TestOSServer/OSInstallFailsIfStreamClosesInTheMiddleOfTransfer
2025-09-05T13:22:10.8511079Z     gnoi_os_test.go:277: OSInstallFailsIfStreamClosesInTheMiddleOfTransfer starts
2025-09-05T13:22:10.8720829Z     gnoi_os_test.go:284: Send TransferRequest
2025-09-05T13:22:10.8734553Z     gnoi_os_test.go:297: Received TransferReady
2025-09-05T13:22:10.8739985Z     gnoi_os_test.go:305: Send TransferContent
2025-09-05T13:22:10.8747920Z     gnoi_os_test.go:316: Received TransferProgress
2025-09-05T13:22:10.8754585Z     gnoi_os_test.go:324: Close the stream immediately
2025-09-05T13:22:10.8755062Z     gnoi_os_test.go:328: Receive error reporting premature closure of the stream
2025-09-05T13:22:10.8764264Z E0905 13:22:10.875062   20907 gnoi_os.go:342] Install: Received EOF instead of TransferContent request!
2025-09-05T13:22:10.8767015Z     gnoi_os_test.go:333: Got expected error from server: rpc error: code = Aborted desc = Stream closed prematurely during transfer.
2025-09-05T13:22:10.8767714Z     gnoi_os_test.go:339: Incomplete transfer has been removed
2025-09-05T13:22:10.8768420Z === RUN   TestOSServer/OSInstallFailsIfWrongMsgIsSentInTheMiddleOfTransfer
2025-09-05T13:22:10.8999676Z E0905 13:22:10.899169   20907 gnoi_os.go:350] Install: Received a TransferReq out-of-sequence.
2025-09-05T13:22:10.9016380Z === RUN   TestOSServer/OSInstallSucceeds
2025-09-05T13:22:10.9250649Z === RUN   TestOSServer/OSInstallFailsIfBackendErrorsOnTransferReady
2025-09-05T13:22:10.9474486Z E0905 13:22:10.946413   20907 gnoi_os.go:69] processTransferReq: Backend returned OS unimplemented error.
2025-09-05T13:22:10.9475315Z E0905 13:22:10.946463   20907 gnoi_os.go:313] Install: TransferReady not received. Returning OS Unimplemented (backend not supported)
2025-09-05T13:22:10.9485552Z === RUN   TestOSServer/OSInstallFailsOnBadTransferReadyJSON
2025-09-05T13:22:10.9707788Z === RUN   TestOSServer/OSInstallFailsWithAuthenticationFailure
2025-09-05T13:22:10.9937234Z === RUN   TestOSServer/OSInstallFailsForConcurrentOperations_SendError
2025-09-05T13:22:10.9956278Z E0905 13:22:10.994077   20907 gnoi_os.go:285] InstallResponse: simulated send error
2025-09-05T13:22:10.9956650Z --- PASS: TestOSServer (1.73s)
2025-09-05T13:22:10.9956898Z     --- PASS: TestOSServer/OSInstallFailsIfTransferRequestIsMissingVersion (0.03s)
2025-09-05T13:22:10.9957161Z     --- PASS: TestOSServer/OSInstallFailsForConcurrentOperations (0.05s)
2025-09-05T13:22:10.9957410Z     --- PASS: TestOSServer/OSInstallFailsIfWrongMessageIsSent (0.02s)
2025-09-05T13:22:10.9957645Z     --- PASS: TestOSServer/OSInstallAbortedImmediately (0.02s)
2025-09-05T13:22:10.9957897Z     --- PASS: TestOSServer/OSInstallFailsIfImageExistsWhenTransferBegins (0.02s)
2025-09-05T13:22:10.9958168Z     --- PASS: TestOSServer/OSInstallFailsIfStreamClosesInTheMiddleOfTransfer (0.03s)
2025-09-05T13:22:10.9958438Z     --- PASS: TestOSServer/OSInstallFailsIfWrongMsgIsSentInTheMiddleOfTransfer (0.02s)
2025-09-05T13:22:10.9958986Z     --- PASS: TestOSServer/OSInstallSucceeds (0.02s)
2025-09-05T13:22:10.9959417Z     --- PASS: TestOSServer/OSInstallFailsIfBackendErrorsOnTransferReady (0.02s)
2025-09-05T13:22:10.9959670Z     --- PASS: TestOSServer/OSInstallFailsOnBadTransferReadyJSON (0.02s)
2025-09-05T13:22:10.9960179Z     --- PASS: TestOSServer/OSInstallFailsWithAuthenticationFailure (0.02s)
2025-09-05T13:22:10.9960445Z     --- PASS: TestOSServer/OSInstallFailsForConcurrentOperations_SendError (0.00s)
2025-09-05T13:22:10.9960805Z === RUN   TestHandleErrorResponse
2025-09-05T13:22:10.9961027Z --- PASS: TestHandleErrorResponse (0.00s)
2025-09-05T13:22:10.9961236Z === RUN   TestHandleErrorResponse_MarshalError
2025-09-05T13:22:10.9965487Z     gnoi_os_test.go:661: Got response: install_error:{detail:"test marshal fail: "}
2025-09-05T13:22:10.9970771Z --- PASS: TestHandleErrorResponse_MarshalError (0.00s)
2025-09-05T13:22:10.9971494Z === RUN   TestProcessTransferContent_OpenFileError
2025-09-05T13:22:10.9973696Z E0905 13:22:10.996611   20907 gnoi_os.go:194] processTransferContent: Failed to open or create file for writing: /tmp/test.img, error: simulated OpenFile failure
2025-09-05T13:22:10.9975019Z     gnoi_os_test.go:684: processTransferContent response=install_error:{detail:"Failed to open file [/tmp/test.img]."}
2025-09-05T13:22:10.9976839Z --- PASS: TestProcessTransferContent_OpenFileError (0.00s)
2025-09-05T13:22:10.9981222Z === RUN   TestProcessTransferContent_WriteError
2025-09-05T13:22:10.9981494Z --- PASS: TestProcessTransferContent_WriteError (0.00s)
2025-09-05T13:22:10.9985007Z === RUN   TestProcessTransferContent_CloseError
2025-09-05T13:22:10.9986375Z --- PASS: TestProcessTransferContent_CloseError (0.00s)
2025-09-05T13:22:10.9987331Z === RUN   TestProcessInstallFromBackEnd_Success
2025-09-05T13:22:10.9988240Z     gnoi_os_test.go:799: ProcessInstallFromBackEnd result=stable
2025-09-05T13:22:10.9988760Z --- PASS: TestProcessInstallFromBackEnd_Success (0.00s)
2025-09-05T13:22:10.9989628Z === RUN   TestProcessInstallFromBackEnd_NewDbusClientFails
2025-09-05T13:22:10.9989872Z     gnoi_os_test.go:811: ProcessInstallFromBackEnd err=dbus error
2025-09-05T13:22:10.9990118Z --- PASS: TestProcessInstallFromBackEnd_NewDbusClientFails (0.00s)
2025-09-05T13:22:10.9990345Z === RUN   TestRemoveIncompleteTrf_RemoveFails
2025-09-05T13:22:10.9990606Z E0905 13:22:10.998335   20907 gnoi_os.go:258] Failed to remove incomplete image: mock remove failure
2025-09-05T13:22:10.9996664Z --- PASS: TestRemoveIncompleteTrf_RemoveFails (0.00s)
2025-09-05T13:22:10.9998988Z === RUN   TestProcessTransferReq_MarshalError
2025-09-05T13:22:11.0001096Z --- PASS: TestProcessTransferReq_MarshalError (0.00s)
2025-09-05T13:22:11.0001381Z === RUN   TestProcessTransferReq_GenericError
2025-09-05T13:22:11.0003620Z E0905 13:22:10.999116   20907 gnoi_os.go:72] processTransferReq: Error in processing install from backend
2025-09-05T13:22:11.0005404Z --- PASS: TestProcessTransferReq_GenericError (0.00s)
2025-09-05T13:22:11.0005927Z === RUN   TestProcessTransferEnd_UnmarshalError
2025-09-05T13:22:11.0006494Z --- PASS: TestProcessTransferEnd_UnmarshalError (0.00s)
2025-09-05T13:22:11.0006881Z === RUN   TestProcessTransferEnd_MarshalError
2025-09-05T13:22:11.0007336Z E0905 13:22:10.999575   20907 gnoi_os.go:104] Failed to marshal TransferEnd JSON: err: mock marshal error, req: , reqStr: []
2025-09-05T13:22:11.0007745Z --- PASS: TestProcessTransferEnd_MarshalError (0.00s)
2025-09-05T13:22:11.0008513Z === RUN   TestProcessTransferEnd_BackendError
2025-09-05T13:22:11.0008810Z E0905 13:22:10.999833   20907 gnoi_os.go:117] Received error from OSServer.TransferEnd: err: this is a backend error, reqStr: [123 125], respStr: 
2025-09-05T13:22:11.0009110Z --- PASS: TestProcessTransferEnd_BackendError (0.00s)

Why I did it

How I did it

How to verify it

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)

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

},
}
// If the file doesn't exist, create it, or append to the file
f, err := os.OpenFile(imgPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this require us to mount /tmp into the container?

Copy link
Contributor Author

@kanchanavelusamy kanchanavelusamy Aug 12, 2025

Choose a reason for hiding this comment

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

Does this require us to mount /tmp into the container?

Based on the HLD, my understanding is that the gNMI server, which runs in a container, receives the OS image data in chunks via the os.Install RPC stream. The processTransferContent function then temporarily saves these chunks to a local file within the container.

Once the entire file has been transferred, the container's role is to pass the completed file to the host for the actual installation using the DBUS communication method as described in the HLD. Therefore, the file only needs to be in the container for the duration of this transfer and doesn't require persistent storage.

@ndas7: Could you please confirm this?
cc: @kishanps

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@kanchanavelusamy
Copy link
Contributor Author

@hdwhdw: I’ve made the suggested changes - please review the updated PR.

cc: @ndas7, @kishanps

@hdwhdw
Copy link
Contributor

hdwhdw commented Aug 13, 2025

@kanchanavelusamy Got it. Meanwhile, is the description (test) stale?

Copy link
Contributor

@hdwhdw hdwhdw left a comment

Choose a reason for hiding this comment

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

Also a general improvement suggestion. We need some more logging on the server side as well. In your PR description, can you also share your gnmi server log and make sure it reflect the entire workflow of an install?

Comment on lines +92 to +93
ProcessTransferReady func(string) (string, error) // Function that handles TransferReady request.
ProcessTransferEnd func(string) (string, error) // Function that handles TransferEnd request.
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this is an appropriate use of Config. if we want to inject implementation for testing, we can inject it into the server struct or monkey patch it, but don't call it a config (let alone putting it into the telemetry binary) .

If everybody starts to do this, the config is going to get unmanageable very soon.

Copy link
Contributor

Choose a reason for hiding this comment

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

Copying the example I raised in another comment

 // Define clear interfaces for dependencies
  type OSInstaller interface {
      ProcessTransferReady(req string) (string, error)
      ProcessTransferEnd(req string) (string, error)
      // Could also be more specific:
      // ValidateTransfer(*ospb.TransferRequest) error
      // StoreImage(version string, content []byte) error
      // CompleteInstallation(version string) error
  }

  type OSServer struct {
      installer OSInstaller  // Inject via constructor
      imgDir    string      // Configuration stays separate
      auth      Authenticator
  }

  // Constructor injection
  func NewOSServer(installer OSInstaller, imgDir string, auth Authenticator) *OSServer {
      return &OSServer{
          installer: installer,
          imgDir:    imgDir,
          auth:      auth,
      }
  }

log.Infof("Response string from backend= %s", respStr)
if err != nil {
// If the error is about unimplemented OS install, return nil to trigger gRPC Unimplemented code
if strings.Contains(err.Error(), "OS Install not supported") {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is extremely fragile, is there a more robust way to handle this. For example comparing error code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is extremely fragile, is there a more robust way to handle this. For example comparing error code?

Addressed.

},
}
// If the file doesn't exist, create it, or append to the file
f, err := os.OpenFile(imgPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
Copy link
Contributor

Choose a reason for hiding this comment

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

We should validate the path, to prevent potential traversal vulnerability.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We should validate the path, to prevent potential traversal vulnerability.

Addressed.

}
defer sem.Unlock()
// Receive TransferReq message.
req, err := stream.Recv()
Copy link
Contributor

Choose a reason for hiding this comment

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

There is an implicit state machine here. If you are from start, you are expecting a TransferRequest, then you are expecting a TransferContent, etc. Can we implement a state machine here? For example, keep track of the current state and the next potential/valid state?

return &ospb.InstallResponse{
Response: &ospb.InstallResponse_TransferProgress{
TransferProgress: &ospb.TransferProgress{
BytesReceived: uint64(len(transferContent)),
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a bug isn't it? We should return the total content received so far, not the length of the current trunk.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a bug isn't it? We should return the total content received so far, not the length of the current trunk.

Addressed.

}
func (srv *OSServer) processTransferEnd(req *ospb.InstallRequest) *ospb.InstallResponse {
// Front end marshals the request, and sends to the sonic-host-service.
// Back end is expected to return the response in JSON format.
Copy link
Contributor

Choose a reason for hiding this comment

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

We can probably use some logging in places like this, i.e. whenever an "event" happen like client has signal transfer being completed, there should be some logs so people can debug.

Copy link
Contributor Author

@kanchanavelusamy kanchanavelusamy Aug 28, 2025

Choose a reason for hiding this comment

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

We can probably use some logging in places like this, i.e. whenever an "event" happen like client has signal transfer being completed, there should be some logs so people can debug.

Addressed.
Sample Logs for Component Test Results

I0829 10:19:35.164142 1453383 gnoi_os.go:274] === [OS Install Start] ===
I0829 10:19:35.164201 1453383 gnoi_os.go:299] Install: Received TransferRequest version=os1.1
I0829 10:19:35.164220 1453383 gnoi_os.go:44] processTransferReq: transfer_request:{version:"os1.1"}
I0829 10:19:35.164346 1453383 gnoi_os.go:71] processTransferReq: Backend response {"transferReady":{}}
I0829 10:19:35.164394 1453383 gnoi_os.go:99] processTransferReq: complete.
I0829 10:19:35.164422 1453383 gnoi_os.go:315] Install: Response received transfer_ready:{}
I0829 10:19:35.164863 1453383 gnoi_os.go:339] Install: Received TransferContent stream
I0829 10:19:35.164899 1453383 gnoi_os.go:148] processTransferContent: file /tmp/os1.1
I0829 10:19:35.165038 1453383 gnoi_os.go:234] processTransferContent: complete. Wrote 54 bytes to /tmp/os1.1
I0829 10:19:35.165063 1453383 gnoi_os.go:387] Install: Response received transfer_progress:{bytes_received:54}
I0829 10:19:35.165389 1453383 gnoi_os.go:339] Install: Received TransferContent stream
I0829 10:19:35.165420 1453383 gnoi_os.go:365] Install: TransferContent is complete.
I0829 10:19:35.165437 1453383 gnoi_os.go:410] Install: Received TransferEnd
I0829 10:19:35.165462 1453383 gnoi_os.go:106] processTransferEnd: transfer_end:{}
I0829 10:19:35.165580 1453383 gnoi_os.go:120] processTransferEnd: Backend response {"validated":{}}
I0829 10:19:35.165630 1453383 gnoi_os.go:143] processTransferEnd: complete.
I0829 10:19:35.165652 1453383 gnoi_os.go:412] Install: Response received validated:{}
I0829 10:19:35.165721 1453383 gnoi_os.go:426] === [OS Install Complete] ===

@kanchanavelusamy
Copy link
Contributor Author

kanchanavelusamy commented Aug 18, 2025

@kanchanavelusamy Got it. Meanwhile, is the description (test) stale?

Hi @hdwhdw
The description is accurate and up to date. The Unimplemented error is expected because while the sonic-gnmi implementation is in this PR, the backend support for the Install RPC is not yet implemented in sonic-host-services that is being tracked in the PR #270.

Install RPC:
admin@sonic:~$ docker exec gnmi gnoi_client -target 127.0.0.1:8080 -notls -module OS -rpc Install -jsonin '{"transferRequest": {"version": "SONiC-OS-master.0-4b447731e", "standby_supervisor": false}}' --input_file=SONiC-OS.tar.gz
OS Install
Error receiving stream: rpc error: code = Unimplemented desc = OS Install not supported
admin@sonic:~$

cc: @ndas7, @kishanps

@kanchanavelusamy
Copy link
Contributor Author

kanchanavelusamy commented Aug 18, 2025

Also a general improvement suggestion. We need some more logging on the server side as well. In your PR description, can you also share your gnmi server log and make sure it reflect the entire workflow of an install?

I've updated the PR description to include the gNMI server log, which reflects the expected "Backend returned unimplemented error" for the Install RPC's current workflow.

2025 Aug 18 09:55:20.942012 sonic INFO gnmi#supervisord: gnmi-native I0818 09:55:20.939733      23 telemetry.go:481] GNMI Server started serving
2025 Aug 18 09:55:20.942012 sonic INFO gnmi#supervisord: gnmi-native 2025/08/18 09:55:20 INFO: [core] [Server #1 ListenSocket #2]ListenSocket created
2025 Aug 18 09:57:15.255104 sonic INFO gnmi#supervisord: gnmi-native I0818 09:57:15.254673      23 gnoi_os.go:189] gNOI: os.Install
2025 Aug 18 09:57:15.255712 sonic INFO gnmi#supervisord: gnmi-native I0818 09:57:15.255484      23 gnoi_os.go:35] Processing *os.InstallRequest_TransferRequest
2025 Aug 18 09:57:15.256148 sonic INFO gnmi#supervisord: gnmi-native I0818 09:57:15.255959      23 dbus_client.go:58] DbusClient: NewDbusClient
2025 Aug 18 09:57:15.258694 sonic INFO gnmi#supervisord: gnmi-native I0818 09:57:15.258509      23 dbus_client.go:72] DbusClient: Close
2025 Aug 18 09:57:15.258917 sonic INFO gnmi#supervisord: gnmi-native I0818 09:57:15.258760      23 gnoi_os.go:63] Response string from backend= 
2025 Aug 18 09:57:15.259120 sonic INFO gnmi#supervisord: gnmi-native I0818 09:57:15.258974      23 gnoi_os.go:67] Backend returned unimplemented error.
2025 Aug 18 09:57:15.259316 sonic INFO gnmi#supervisord: gnmi-native I0818 09:57:15.259174      23 gnoi_os.go:227] Returning codes.Unimplemented as backend not supported

Server-side logs indicating successful OS installation scenarios:

I0829 10:19:35.164142 1453383 gnoi_os.go:274] === [OS Install Start] ===
I0829 10:19:35.164201 1453383 gnoi_os.go:299] Install: Received TransferRequest version=os1.1
I0829 10:19:35.164220 1453383 gnoi_os.go:44] processTransferReq: transfer_request:{version:"os1.1"}
I0829 10:19:35.164346 1453383 gnoi_os.go:71] processTransferReq: Backend response {"transferReady":{}}
I0829 10:19:35.164394 1453383 gnoi_os.go:99] processTransferReq: complete.
I0829 10:19:35.164422 1453383 gnoi_os.go:315] Install: Response received transfer_ready:{}
I0829 10:19:35.164863 1453383 gnoi_os.go:339] Install: Received TransferContent stream
I0829 10:19:35.164899 1453383 gnoi_os.go:148] processTransferContent: file /tmp/os1.1
I0829 10:19:35.165038 1453383 gnoi_os.go:234] processTransferContent: complete. Wrote 54 bytes to /tmp/os1.1
I0829 10:19:35.165063 1453383 gnoi_os.go:387] Install: Response received transfer_progress:{bytes_received:54}
I0829 10:19:35.165389 1453383 gnoi_os.go:339] Install: Received TransferContent stream
I0829 10:19:35.165420 1453383 gnoi_os.go:365] Install: TransferContent is complete.
I0829 10:19:35.165437 1453383 gnoi_os.go:410] Install: Received TransferEnd
I0829 10:19:35.165462 1453383 gnoi_os.go:106] processTransferEnd: transfer_end:{}
I0829 10:19:35.165580 1453383 gnoi_os.go:120] processTransferEnd: Backend response {"validated":{}}
I0829 10:19:35.165630 1453383 gnoi_os.go:143] processTransferEnd: complete.
I0829 10:19:35.165652 1453383 gnoi_os.go:412] Install: Response received validated:{}
I0829 10:19:35.165721 1453383 gnoi_os.go:426] === [OS Install Complete] ===

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@kanchanavelusamy kanchanavelusamy marked this pull request as draft October 14, 2025 05:44
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.

4 participants