Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a0e8682
gNOI System APIs (Reboot, RebootStatus, Cancelreboot) changes
ndas7 Oct 16, 2024
df12586
gNOI System APIs (Reboot, RebootStatus, Cancelreboot) changes
ndas7 Oct 16, 2024
d684c78
gNOI System APIs (Reboot, RebootStatus, Cancelreboot) changes
ndas7 Oct 16, 2024
58dc8bc
gNOI System APIs (Reboot, RebootStatus, Cancelreboot) changes
ndas7 Oct 16, 2024
e231e75
gNOI System APIs (Reboot, RebootStatus, Cancelreboot) changes
ndas7 Oct 16, 2024
457de62
gNOI System APIs (Reboot, RebootStatus, Cancelreboot) changes
ndas7 Oct 16, 2024
bfef03a
gNOI System APIs (Reboot, RebootStatus, CancelReboot) changes
ndas7 Oct 31, 2024
d2bcd6c
gNOI System APIs (Reboot, RebootStatus, CancelReboot) changes
ndas7 Oct 31, 2024
4ab6795
Merge branch 'master' into gnoi_reboot
ndas7 Dec 12, 2024
d4f6ae2
gNOI System APIs (Reboot, RebootStatus, CancelReboot) changes
ndas7 Oct 31, 2024
55e88d1
gNOI System APIs (Reboot, RebootStatus, CancelReboot) changes
ndas7 Oct 31, 2024
1f6e82a
Merge branch 'sonic-net:master' into gnoi_reboot
ndas7 Jan 8, 2025
4f8b08c
Update gnoi_system.go
ndas7 Jan 9, 2025
32277ed
Update gnoi_system.go
ndas7 Jan 9, 2025
f63d712
Update gnoi_system_test.go
ndas7 Jan 10, 2025
caf0ea2
Update gnoi_system.go
ndas7 Jan 10, 2025
e370d8a
Merge branch 'master' into gnoi_reboot
ndas7 Jan 10, 2025
1c175b9
Update gnoi_system.go
ndas7 Jan 10, 2025
f5c9091
Merge branch 'master' into gnoi_reboot
ndas7 Jan 24, 2025
72965a1
Merge branch 'master' into gnoi_reboot
ndas7 Jan 30, 2025
9d2f425
Update gnoi_system.go
ndas7 Jan 31, 2025
51fe3cd
Update gnoi_system_test.go
ndas7 Jan 31, 2025
2a04d63
Update swss_util.go
ndas7 Jan 31, 2025
a194fdf
Merge branch 'master' into gnoi_reboot
ndas7 Feb 7, 2025
66455ed
Update go.sum
ndas7 Feb 7, 2025
4ceab6a
Update gnoi_system.go
ndas7 Feb 13, 2025
76e110b
Update gnoi_system_test.go
ndas7 Feb 13, 2025
5b0c49f
Merge branch 'master' into gnoi_reboot
ndas7 Feb 13, 2025
06dc0e2
Update Go formatting for files
ndas7 Feb 13, 2025
c3a58eb
Remove old way of HALT Reboot method (#1)
vvolam Feb 14, 2025
cfb8d78
Fix test_gnoi_reboot_halt
vvolam Feb 14, 2025
b11e9b1
Merge branch 'master' into gnoi_reboot
ndas7 Feb 20, 2025
226fc74
Update go.mod and go.sum files
ndas7 Feb 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions common_utils/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ const (
DBUS_STOP_SERVICE
DBUS_RESTART_SERVICE
DBUS_FILE_STAT
DBUS_HALT_SYSTEM
DBUS_IMAGE_DOWNLOAD
DBUS_IMAGE_INSTALL
DBUS_IMAGE_LIST
Expand Down Expand Up @@ -96,8 +95,6 @@ func (c CounterType) String() string {
return "DBUS restart service"
case DBUS_FILE_STAT:
return "DBUS file stat"
case DBUS_HALT_SYSTEM:
Copy link
Collaborator

Choose a reason for hiding this comment

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

DBUS_HALT_SYSTEM

@vvolam your code is deleted. Could you double check?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi Qi, the DBUS handling for HALT method was removed since HALT will now use the Reboot Notification Channel similar to the other Reboot Methods. Hence, this code was removed through Vasundhara's commit https://github.com/ndas7/sonic-gnmi/pull/1/files merged into this PR

return "DBUS halt system"
case DBUS_IMAGE_DOWNLOAD:
return "DBUS image download"
case DBUS_IMAGE_INSTALL:
Expand Down
89 changes: 89 additions & 0 deletions common_utils/notification_producer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package common_utils

import (
"encoding/json"
"fmt"

"github.com/go-redis/redis"
log "github.com/golang/glog"
sdcfg "github.com/sonic-net/sonic-gnmi/sonic_db_config"
)

const (
dbName = "STATE_DB"
)

func GetRedisDBClient() (*redis.Client, error) {
ns, _ := sdcfg.GetDbDefaultNamespace()
addr, err := sdcfg.GetDbTcpAddr(dbName, ns)
if err != nil {
log.Errorf("Addr err: %v", err)
return nil, err
}
db, err := sdcfg.GetDbId("STATE_DB", ns)
if err != nil {
log.Errorf("DB err: %v", err)
return nil, err
}
rclient := redis.NewClient(&redis.Options{
Network: "tcp",
Addr: addr,
Password: "", // no password set
DB: db,
DialTimeout: 0,
})
if rclient == nil {
return nil, fmt.Errorf("Cannot create redis client.")
}
if _, err := rclient.Ping().Result(); err != nil {
return nil, err
}
return rclient, nil
}

// NotificationProducer provides utilities for sending messages using notification channel.
// NewNotificationProducer must be called for a new producer.
// Close must be called when finished.
type NotificationProducer struct {
ch string
rc *redis.Client
}

// NewNotificationProducer returns a new NotificationProducer.
func NewNotificationProducer(ch string) (*NotificationProducer, error) {
n := new(NotificationProducer)
n.ch = ch

// Create redis client.
var err error
n.rc, err = GetRedisDBClient()
if err != nil {
return nil, err
}

return n, nil
}

// Close performs cleanup works.
// Close must be called when finished.
func (n *NotificationProducer) Close() {
if n.rc != nil {
n.rc.Close()
}
}

func (n *NotificationProducer) Send(op, data string, kvs map[string]string) error {
fvs := []string{op, data}
for k, v := range kvs {
fvs = append(fvs, k)
fvs = append(fvs, v)
}

val, err := json.Marshal(fvs)
if err != nil {
log.Error(err.Error())
return err
}
log.Infof("Publishing to channel %s: %v.", n.ch, string(val))
return n.rc.Publish(n.ch, val).Err()
}
49 changes: 49 additions & 0 deletions common_utils/notification_producer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package common_utils

import (
"testing"
)

const (
channel string = "channel"
)

func TestNotificationProducerSucceedsWithEmptyOp(t *testing.T) {
n, _ := NewNotificationProducer(channel)
defer n.Close()
if err := n.Send("", "somedata", map[string]string{}); err != nil {
t.Fatalf("Expected no error!")
}
}

func TestNotificationProducerSucceedsWithEmptyData(t *testing.T) {
n, _ := NewNotificationProducer(channel)
defer n.Close()
if err := n.Send("someop", "", map[string]string{}); err != nil {
t.Fatalf("Expected no error!")
}
}

func TestNotificationProducerSucceedsWithEmptyOpAndData(t *testing.T) {
n, _ := NewNotificationProducer(channel)
defer n.Close()
if err := n.Send("", "", map[string]string{}); err != nil {
t.Fatalf("Expected no error!")
}
}

func TestNotificationProducerSucceedsWithEmptyKeyValues(t *testing.T) {
n, _ := NewNotificationProducer(channel)
defer n.Close()
if err := n.Send("someop", "somedata", map[string]string{}); err != nil {
t.Fatalf("Expected no error!")
}
}

func TestNotificationProducerSucceeds(t *testing.T) {
n, _ := NewNotificationProducer(channel)
defer n.Close()
if err := n.Send("someop", "somedata", map[string]string{"somekey": "somevalue"}); err != nil {
t.Fatalf("Expected no error!")
}
}
184 changes: 4 additions & 180 deletions gnmi_server/gnoi.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package gnmi
import (
"context"
"encoding/json"
"errors"
io "io/ioutil"
"os"
"os/user"
"strconv"
Expand All @@ -15,8 +13,6 @@ import (
log "github.com/golang/glog"
gnoi_file_pb "github.com/openconfig/gnoi/file"
gnoi_os_pb "github.com/openconfig/gnoi/os"
gnoi_system_pb "github.com/openconfig/gnoi/system"
"github.com/sonic-net/sonic-gnmi/common_utils"
spb "github.com/sonic-net/sonic-gnmi/proto/gnoi"
spb_jwt "github.com/sonic-net/sonic-gnmi/proto/gnoi/jwt"
ssc "github.com/sonic-net/sonic-gnmi/sonic_service_client"
Expand All @@ -25,6 +21,10 @@ import (
"google.golang.org/grpc/status"
)

const (
stateDB string = "STATE_DB"
)

func ReadFileStat(path string) (*gnoi_file_pb.StatInfo, error) {
sc, err := ssc.NewDbusClient()
if err != nil {
Expand Down Expand Up @@ -97,29 +97,6 @@ func (srv *FileServer) Get(req *gnoi_file_pb.GetRequest, stream gnoi_file_pb.Fil
return status.Errorf(codes.Unimplemented, "")
}

func KillOrRestartProcess(restart bool, serviceName string) error {
sc, err := ssc.NewDbusClient()
if err != nil {
return err
}
defer sc.Close()

if restart {
log.V(2).Infof("Restarting service %s...", serviceName)
err = sc.RestartService(serviceName)
if err != nil {
log.V(2).Infof("Failed to restart service %s: %v", serviceName, err)
}
} else {
log.V(2).Infof("Stopping service %s...", serviceName)
err = sc.StopService(serviceName)
if err != nil {
log.V(2).Infof("Failed to stop service %s: %v", serviceName, err)
}
}
return err
}

func (srv *OSServer) Verify(ctx context.Context, req *gnoi_os_pb.VerifyRequest) (*gnoi_os_pb.VerifyResponse, error) {
_, err := authenticate(srv.config, ctx, false)
if err != nil {
Expand Down Expand Up @@ -212,159 +189,6 @@ func (srv *OSServer) Activate(ctx context.Context, req *gnoi_os_pb.ActivateReque
return &resp, nil
}

func (srv *SystemServer) KillProcess(ctx context.Context, req *gnoi_system_pb.KillProcessRequest) (*gnoi_system_pb.KillProcessResponse, error) {
_, err := authenticate(srv.config, ctx, true)
if err != nil {
return nil, err
}

serviceName := req.GetName()
restart := req.GetRestart()
if req.GetPid() != 0 {
return nil, status.Errorf(codes.Unimplemented, "Pid option is not implemented")
}
if req.GetSignal() != gnoi_system_pb.KillProcessRequest_SIGNAL_TERM {
return nil, status.Errorf(codes.Unimplemented, "KillProcess only supports SIGNAL_TERM (option 1) for graceful process termination. Please specify SIGNAL_TERM")
}
log.V(1).Info("gNOI: KillProcess with optional restart")
log.V(1).Info("Request: ", req)
err = KillOrRestartProcess(restart, serviceName)
if err != nil {
return nil, err
}
var resp gnoi_system_pb.KillProcessResponse
return &resp, nil
}

func HaltSystem() error {
sc, err := ssc.NewDbusClient()
if err != nil {
return err
}
defer sc.Close()

log.V(2).Infof("Halting the system..")
err = sc.HaltSystem()
if err != nil {
log.V(2).Infof("Failed to Halt the system %v", err)
}
return err
}

func RebootSystem(fileName string) error {
log.V(2).Infof("Rebooting with %s...", fileName)
sc, err := ssc.NewDbusClient()
if err != nil {
return err
}
defer sc.Close()

err = sc.ConfigReload(fileName)
return err
}

func (srv *SystemServer) Reboot(ctx context.Context, req *gnoi_system_pb.RebootRequest) (*gnoi_system_pb.RebootResponse, error) {
fileName := common_utils.GNMI_WORK_PATH + "/config_db.json.tmp"

_, err := authenticate(srv.config, ctx, true)
if err != nil {
return nil, err
}
log.V(1).Info("gNOI: Reboot")
log.V(1).Info("Request:", req)

// Check the reboot type
switch req.GetMethod() {
case gnoi_system_pb.RebootMethod_HALT:
log.V(1).Info("Reboot method is HALT. Halting the system...")
err = HaltSystem()
if err != nil {
return nil, err
}
default:
log.V(1).Info("Reboot system now, delay is ignored...")
// TODO: Support GNOI reboot delay
// Delay in nanoseconds before issuing reboot.
// https://github.com/openconfig/gnoi/blob/master/system/system.proto#L102-L115
config_db_json, err := io.ReadFile(fileName)
if errors.Is(err, os.ErrNotExist) {
fileName = ""
}
err = RebootSystem(string(config_db_json))
if err != nil {
return nil, err
}
}

var resp gnoi_system_pb.RebootResponse
return &resp, nil
}

// TODO: Support GNOI RebootStatus
func (srv *SystemServer) RebootStatus(ctx context.Context, req *gnoi_system_pb.RebootStatusRequest) (*gnoi_system_pb.RebootStatusResponse, error) {
_, err := authenticate(srv.config, ctx, false)
if err != nil {
return nil, err
}
log.V(1).Info("gNOI: RebootStatus")
return nil, status.Errorf(codes.Unimplemented, "")
}

// TODO: Support GNOI CancelReboot
func (srv *SystemServer) CancelReboot(ctx context.Context, req *gnoi_system_pb.CancelRebootRequest) (*gnoi_system_pb.CancelRebootResponse, error) {
_, err := authenticate(srv.config, ctx, true)
if err != nil {
return nil, err
}
log.V(1).Info("gNOI: CancelReboot")
return nil, status.Errorf(codes.Unimplemented, "")
}
func (srv *SystemServer) Ping(req *gnoi_system_pb.PingRequest, rs gnoi_system_pb.System_PingServer) error {
ctx := rs.Context()
_, err := authenticate(srv.config, ctx, true)
if err != nil {
return err
}
log.V(1).Info("gNOI: Ping")
return status.Errorf(codes.Unimplemented, "")
}
func (srv *SystemServer) Traceroute(req *gnoi_system_pb.TracerouteRequest, rs gnoi_system_pb.System_TracerouteServer) error {
ctx := rs.Context()
_, err := authenticate(srv.config, ctx, true)
if err != nil {
return err
}
log.V(1).Info("gNOI: Traceroute")
return status.Errorf(codes.Unimplemented, "")
}
func (srv *SystemServer) SetPackage(rs gnoi_system_pb.System_SetPackageServer) error {
ctx := rs.Context()
_, err := authenticate(srv.config, ctx, true)
if err != nil {
return err
}
log.V(1).Info("gNOI: SetPackage")
return status.Errorf(codes.Unimplemented, "")
}
func (srv *SystemServer) SwitchControlProcessor(ctx context.Context, req *gnoi_system_pb.SwitchControlProcessorRequest) (*gnoi_system_pb.SwitchControlProcessorResponse, error) {
_, err := authenticate(srv.config, ctx, true)
if err != nil {
return nil, err
}
log.V(1).Info("gNOI: SwitchControlProcessor")
return nil, status.Errorf(codes.Unimplemented, "")
}
func (srv *SystemServer) Time(ctx context.Context, req *gnoi_system_pb.TimeRequest) (*gnoi_system_pb.TimeResponse, error) {
_, err := authenticate(srv.config, ctx, false)
if err != nil {
return nil, err
}
log.V(1).Info("gNOI: Time")
var tm gnoi_system_pb.TimeResponse
tm.Time = uint64(time.Now().UnixNano())
return &tm, nil
}

func (srv *Server) Authenticate(ctx context.Context, req *spb_jwt.AuthenticateRequest) (*spb_jwt.AuthenticateResponse, error) {
// Can't enforce normal authentication here.. maybe only enforce client cert auth if enabled?
// ctx,err := authenticate(srv.config, ctx, false)
Expand Down
Loading