Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve GNMI full config update #312

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions common_utils/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const (
DBUS_STOP_SERVICE
DBUS_RESTART_SERVICE
DBUS_FILE_STAT
DBUS_VALIDATE_YANG
DBUS_HALT_SYSTEM
COUNTER_SIZE
)
Expand Down
29 changes: 1 addition & 28 deletions gnmi_server/gnoi.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package gnmi

import (
"context"
"errors"
"os"
"strconv"
"strings"
gnoi_system_pb "github.com/openconfig/gnoi/system"
Expand All @@ -12,10 +10,8 @@ import (
"time"
spb "github.com/sonic-net/sonic-gnmi/proto/gnoi"
transutil "github.com/sonic-net/sonic-gnmi/transl_utils"
io "io/ioutil"
ssc "github.com/sonic-net/sonic-gnmi/sonic_service_client"
spb_jwt "github.com/sonic-net/sonic-gnmi/proto/gnoi/jwt"
"github.com/sonic-net/sonic-gnmi/common_utils"
"google.golang.org/grpc/status"
"google.golang.org/grpc/codes"
"os/user"
Expand Down Expand Up @@ -153,19 +149,7 @@ func HaltSystem() error {
return err
}

func RebootSystem(fileName string) error {
log.V(2).Infof("Rebooting with %s...", fileName)
sc, err := ssc.NewDbusClient()
if err != nil {
return err
}
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)
if err != nil {
return nil, err
Expand All @@ -182,18 +166,7 @@ func (srv *SystemServer) Reboot(ctx context.Context, req *gnoi_system_pb.RebootR
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
}
return nil, status.Errorf(codes.Unimplemented, "")
}

var resp gnoi_system_pb.RebootResponse
Expand Down
10 changes: 0 additions & 10 deletions gnmi_server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3839,14 +3839,6 @@ func TestRecoverFromJSONSerializationPanic(t *testing.T) {
}

func TestGnmiSetBatch(t *testing.T) {
mockCode :=
`
print('No Yang validation for test mode...')
print('%s')
`
mock1 := gomonkey.ApplyGlobalVar(&sdc.PyCodeForYang, mockCode)
defer mock1.Reset()

sdcfg.Init()
s := createServer(t, 8090)
go runServer(t, s)
Expand Down Expand Up @@ -3925,8 +3917,6 @@ func TestGNMINative(t *testing.T) {
return &dbus.Call{}
})
defer mock2.Reset()
mock3 := gomonkey.ApplyFunc(sdc.RunPyCode, func(text string) error {return nil})
defer mock3.Reset()

sdcfg.Init()
s := createServer(t, 8080)
Expand Down
61 changes: 18 additions & 43 deletions sonic_data_client/mixed_db_client.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package client

// #cgo pkg-config: python3-embed
// #include <Python.h>
import "C"

import (
"bytes"
"encoding/json"
Expand All @@ -16,7 +12,6 @@ import (
"strings"
"sync"
"time"
"unsafe"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
log "github.com/golang/glog"
Expand Down Expand Up @@ -1177,37 +1172,6 @@ func (c *MixedDbClient) ConvertToJsonPatch(prefix *gnmipb.Path, path *gnmipb.Pat
return nil
}

func RunPyCode(text string) error {
defer C.Py_Finalize()
C.Py_Initialize()
PyCodeInC := C.CString(text)
defer C.free(unsafe.Pointer(PyCodeInC))
CRet := C.PyRun_SimpleString(PyCodeInC)
if int(CRet) != 0 {
return fmt.Errorf("Python failure")
}
return nil
}

var PyCodeForYang string =
`
import sonic_yang
import json

yang_parser = sonic_yang.SonicYang("/usr/local/yang-models")
yang_parser.loadYangModel()
filename = "%s"
with open(filename, 'r') as fp:
text = fp.read()

try:
yang_parser.loadData(configdbJson=json.loads(text))
yang_parser.validate_data_tree()
except sonic_yang.SonicYangException as e:
print("Yang validation error: {}".format(str(e)))
raise
`

func (c *MixedDbClient) SetIncrementalConfig(delete []*gnmipb.Path, replace []*gnmipb.Update, update []*gnmipb.Update) error {
var err error

Expand Down Expand Up @@ -1362,17 +1326,28 @@ func (c *MixedDbClient) SetFullConfig(delete []*gnmipb.Path, replace []*gnmipb.U
if len(ietf_json_val) == 0 {
return fmt.Errorf("Value encoding is not IETF JSON")
}
content := []byte(ietf_json_val)
fileName := c.workPath + "/config_db.json.tmp"
err := ioutil.WriteFile(fileName, content, 0644)

var sc ssc.Service
sc, err := ssc.NewDbusClient()
if err != nil {
return err
}

PyCodeInGo := fmt.Sprintf(PyCodeForYang, fileName)
err = RunPyCode(PyCodeInGo)
log.V(2).Infof("Run yang validation")
err = sc.ValidateYang(string(ietf_json_val))
if err != nil {
return err
}
log.V(2).Infof("Run config reload")
err = sc.ConfigReload(string(ietf_json_val), "gnmi")
if err != nil {
return fmt.Errorf("Yang validation failed!")
log.V(2).Infof("Recover default config")
sc.ConfigReloadForce("", "gnmi")
return err
}
log.V(2).Infof("Run config save")
err = sc.ConfigSave("")
if err != nil {
return err
}

return nil
Expand Down
28 changes: 25 additions & 3 deletions sonic_service_client/dbus_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import (
)

type Service interface {
ConfigReload(fileName string) error
ConfigReload(config string, caller string) error
ConfigReloadForce(config string, caller string) error
ConfigSave(fileName string) error
ApplyPatchYang(fileName string) error
ApplyPatchDb(fileName string) error
Expand All @@ -19,6 +20,7 @@ type Service interface {
StopService(service string) error
RestartService(service string) error
GetFileStat(path string) (map[string]string, error)
ValidateYang(config string) error
HaltSystem() error
}

Expand Down Expand Up @@ -99,13 +101,23 @@ func DbusApi(busName string, busPath string, intName string, timeout int, args .
}
}

func (c *DbusClient) ConfigReload(config string) error {
func (c *DbusClient) ConfigReload(config string, caller string) error {
common_utils.IncCounter(common_utils.DBUS_CONFIG_RELOAD)
modName := "config"
busName := c.busNamePrefix + modName
busPath := c.busPathPrefix + modName
intName := c.intNamePrefix + modName + ".reload"
_, err := DbusApi(busName, busPath, intName, 60, config)
_, err := DbusApi(busName, busPath, intName, 240, config, caller)
return err
}

func (c *DbusClient) ConfigReloadForce(config string, caller string) error {
common_utils.IncCounter(common_utils.DBUS_CONFIG_RELOAD)
modName := "config"
busName := c.busNamePrefix + modName
busPath := c.busPathPrefix + modName
intName := c.intNamePrefix + modName + ".reload_force"
_, err := DbusApi(busName, busPath, intName, 240, config, caller)
return err
}

Expand Down Expand Up @@ -193,6 +205,16 @@ func (c *DbusClient) GetFileStat(path string) (map[string]string, error) {
return data, nil
}

func (c *DbusClient) ValidateYang(config string) error {
common_utils.IncCounter(common_utils.DBUS_VALIDATE_YANG)
modName := "yang"
busName := c.busNamePrefix + modName
busPath := c.busPathPrefix + modName
intName := c.intNamePrefix + modName + ".validate"
_, err := DbusApi(busName, busPath, intName, 60, config)
return err
}

func (c *DbusClient) HaltSystem() error {
// Increment the counter for the DBUS_HALT_SYSTEM event
common_utils.IncCounter(common_utils.DBUS_HALT_SYSTEM)
Expand Down
Loading
Loading