diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..d8d1d34c --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,21 @@ +name: Go Checks + +on: + pull_request: {} + push: + branches: + - main + +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: actions/setup-go@v5 + with: + go-version-file: 'go.mod' + - name: golangci-lint + uses: golangci/golangci-lint-action@v8 + with: + version: v2.4 diff --git a/client/cmd/data_blameConfig.go b/client/cmd/data_blameConfig.go index deb5ac0a..968e0ec9 100644 --- a/client/cmd/data_blameConfig.go +++ b/client/cmd/data_blameConfig.go @@ -43,7 +43,7 @@ var dataBlameConfig = &cobra.Command{ } b, err := opts.Marshal(rsp.ConfigTree) if err != nil { - fmt.Fprintf(os.Stdout, "%v", err) + _, _ = fmt.Fprintf(os.Stdout, "%v", err) } fmt.Println(string(b)) } diff --git a/client/cmd/datastore_get.go b/client/cmd/datastore_get.go index 9e701894..e1ab1b49 100644 --- a/client/cmd/datastore_get.go +++ b/client/cmd/datastore_get.go @@ -73,8 +73,8 @@ func printDataStoreTable(rsp *sdcpb.GetDataStoreResponse) { table := tablewriter.NewWriter(os.Stdout) table.Header([]string{"Name", "Schema", "Protocol", "Address", "State"}) table.Options(tablewriter.WithAlignment(tw.Alignment{tw.AlignLeft})) - table.Bulk(toTableData(rsp)) - table.Render() + _ = table.Bulk(toTableData(rsp)) + _ = table.Render() } func toTableData(rsp *sdcpb.GetDataStoreResponse) [][]string { diff --git a/client/cmd/datastore_list.go b/client/cmd/datastore_list.go index 57553133..b49b2a5b 100644 --- a/client/cmd/datastore_list.go +++ b/client/cmd/datastore_list.go @@ -78,6 +78,6 @@ func printDataStoresTable(rsp *sdcpb.ListDataStoreResponse) { table := tablewriter.NewWriter(os.Stdout) table.Header([]string{"Name", "Schema", "Protocol", "Address", "State", "Candidate (C/O/P)"}) table.Options(tablewriter.WithAlignment(tw.Alignment{tw.AlignLeft})) - table.Bulk(tableData) - table.Render() + _ = table.Bulk(tableData) + _ = table.Render() } diff --git a/client/cmd/root.go b/client/cmd/root.go index 29f56f3c..fd4e29ff 100644 --- a/client/cmd/root.go +++ b/client/cmd/root.go @@ -57,8 +57,8 @@ func init() { func createDataClient(ctx context.Context, addr string) (sdcpb.DataServerClient, error) { ctx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() - cc, err := grpc.DialContext(ctx, addr, - grpc.WithBlock(), + cc, err := grpc.DialContext(ctx, addr, //nolint:staticcheck + grpc.WithBlock(), //nolint:staticcheck grpc.WithTransportCredentials( insecure.NewCredentials(), ), diff --git a/main.go b/main.go index 724bd8fe..b23186e4 100644 --- a/main.go +++ b/main.go @@ -31,7 +31,6 @@ import ( "github.com/sdcio/data-server/pkg/config" "github.com/sdcio/data-server/pkg/server" "github.com/sdcio/logger" - logf "github.com/sdcio/logger" "github.com/spf13/pflag" ) @@ -58,7 +57,7 @@ func main() { slogOpts := &slog.HandlerOptions{ Level: slog.LevelInfo, - ReplaceAttr: logf.ReplaceTimeAttr, + ReplaceAttr: logger.ReplaceTimeAttr, } if debug { slogOpts.Level = slog.Level(-logger.VDebug) @@ -68,8 +67,8 @@ func main() { } log := logr.FromSlogHandler(slog.NewJSONHandler(os.Stdout, slogOpts)) - logf.SetDefaultLogger(log) - ctx := logf.IntoContext(context.Background(), log) + logger.SetDefaultLogger(log) + ctx := logger.IntoContext(context.Background(), log) go func() { log.Info("pprof server started", "address", "localhost:6060") diff --git a/pkg/datastore/datastore_rpc.go b/pkg/datastore/datastore_rpc.go index 1e030e09..7796ef30 100644 --- a/pkg/datastore/datastore_rpc.go +++ b/pkg/datastore/datastore_rpc.go @@ -22,7 +22,6 @@ import ( "time" "github.com/sdcio/logger" - logf "github.com/sdcio/logger" sdcpb "github.com/sdcio/sdc-protos/sdcpb" "google.golang.org/grpc" @@ -77,11 +76,11 @@ func New(ctx context.Context, c *config.DatastoreConfig, sc schema.Client, cc ca ctx, cancel := context.WithCancel(ctx) - log := logf.FromContext(ctx) + log := logger.FromContext(ctx) log = log.WithName("datastore").WithValues( "datastore-name", c.Name, ) - ctx = logf.IntoContext(ctx, log) + ctx = logger.IntoContext(ctx, log) log.Info("new datastore", "target-name", c.Name, @@ -144,11 +143,11 @@ func (d *Datastore) IntentsList(ctx context.Context) ([]string, error) { } func (d *Datastore) initCache(ctx context.Context) { - log := logf.FromContext(ctx) + log := logger.FromContext(ctx) exists := d.cacheClient.InstanceExists(ctx) if exists { - log.V(logf.VDebug).Info("cache already exists") + log.V(logger.VDebug).Info("cache already exists") return } log.Info("creating cache instance") @@ -162,7 +161,7 @@ CREATE: } func (d *Datastore) connectSBI(ctx context.Context, opts ...grpc.DialOption) error { - log := logf.FromContext(ctx) + log := logger.FromContext(ctx) var err error d.sbi, err = target.New(ctx, d.config.Name, d.config.SBI, d.schemaClient, d, d.config.Sync.Config, d.taskPool, opts...) @@ -222,7 +221,7 @@ func (d *Datastore) Stop(ctx context.Context) error { } err := d.sbi.Close(ctx) if err != nil { - logf.DefaultLogger.Error(err, "datastore failed to close the target connection", "datastore-name", d.Name()) + logger.DefaultLogger.Error(err, "datastore failed to close the target connection", "datastore-name", d.Name()) } return nil } @@ -248,6 +247,9 @@ func (d *Datastore) BlameConfig(ctx context.Context, includeDefaults bool) (*sdc bcp := tree.NewBlameConfigProcessor(tree.NewBlameConfigProcessorConfig(includeDefaults)) bte, err := bcp.Run(ctx, root.GetRoot(), blamePool) + if err != nil { + return nil, err + } // set the root level elements name to the target name bte.Name = d.config.Name diff --git a/pkg/datastore/deviations.go b/pkg/datastore/deviations.go index cf8e60bf..7b1f215a 100644 --- a/pkg/datastore/deviations.go +++ b/pkg/datastore/deviations.go @@ -7,7 +7,6 @@ import ( "github.com/sdcio/data-server/pkg/config" treetypes "github.com/sdcio/data-server/pkg/tree/types" "github.com/sdcio/logger" - logf "github.com/sdcio/logger" sdcpb "github.com/sdcio/sdc-protos/sdcpb" "google.golang.org/grpc/codes" "google.golang.org/grpc/peer" @@ -15,7 +14,7 @@ import ( ) func (d *Datastore) WatchDeviations(req *sdcpb.WatchDeviationRequest, stream sdcpb.DataServer_WatchDeviationsServer) error { - log := logf.FromContext(d.ctx) + log := logger.FromContext(d.ctx) ctx := stream.Context() p, ok := peer.FromContext(ctx) @@ -33,7 +32,7 @@ func (d *Datastore) WatchDeviations(req *sdcpb.WatchDeviationRequest, stream sdc } func (d *Datastore) StopDeviationsWatch(stream sdcpb.DataServer_WatchDeviationsServer) { - log := logf.FromContext(d.ctx) + log := logger.FromContext(d.ctx) d.m.Lock() defer d.m.Unlock() peer := d.deviationClients[stream] @@ -42,8 +41,8 @@ func (d *Datastore) StopDeviationsWatch(stream sdcpb.DataServer_WatchDeviationsS } func (d *Datastore) DeviationMgr(ctx context.Context, c *config.DeviationConfig) { - log := logf.FromContext(ctx).WithName("DeviationManager").WithValues("target-name", d.config.Name) - ctx = logf.IntoContext(ctx, log) + log := logger.FromContext(ctx).WithName("DeviationManager").WithValues("target-name", d.config.Name) + ctx = logger.IntoContext(ctx, log) log.Info("starting deviation manager") ticker := time.NewTicker(c.Interval) @@ -57,7 +56,7 @@ func (d *Datastore) DeviationMgr(ctx context.Context, c *config.DeviationConfig) log.Info("datastore context done, stopping deviation manager") return case <-ticker.C: - log.V(logf.VDebug).Info("deviation calc run - start") + log.V(logger.VDebug).Info("deviation calc run - start") deviationClients := map[string]sdcpb.DataServer_WatchDeviationsServer{} deviationClientNames := make([]string, 0, len(d.deviationClients)) @@ -76,10 +75,10 @@ func (d *Datastore) DeviationMgr(ctx context.Context, c *config.DeviationConfig) } }() if len(deviationClients) == 0 { - log.V(logf.VDebug).Info("no deviation clients present") + log.V(logger.VDebug).Info("no deviation clients present") continue } - log.V(logf.VDebug).Info("deviation clients", "clients", deviationClientNames) + log.V(logger.VDebug).Info("deviation clients", "clients", deviationClientNames) for clientIdentifier, dc := range deviationClients { err := dc.Send(&sdcpb.WatchDeviationResponse{ Name: d.config.Name, @@ -95,7 +94,7 @@ func (d *Datastore) DeviationMgr(ctx context.Context, c *config.DeviationConfig) log.Error(err, "failed to calculate deviations") continue } - log.V(logf.VDebug).Info("calculate deviations", "duration", time.Since(start)) + log.V(logger.VDebug).Info("calculate deviations", "duration", time.Since(start)) d.SendDeviations(ctx, deviationChan, deviationClients) log.Info("Before sending DeviationEvent_END") for clientIdentifier, dc := range deviationClients { @@ -110,13 +109,13 @@ func (d *Datastore) DeviationMgr(ctx context.Context, c *config.DeviationConfig) log.Error(err, "error sending deviation", "client-identifier", clientIdentifier) } } - log.V(logf.VDebug).Info("deviation calc run - finished") + log.V(logger.VDebug).Info("deviation calc run - finished") } } } func (d *Datastore) SendDeviations(ctx context.Context, ch <-chan *treetypes.DeviationEntry, deviationClients map[string]sdcpb.DataServer_WatchDeviationsServer) { - log := logf.FromContext(ctx) + log := logger.FromContext(ctx) for deviation := range ch { for clientIdentifier, dc := range deviationClients { if dc.Context().Err() != nil { @@ -141,7 +140,7 @@ func (d *Datastore) SendDeviations(ctx context.Context, ch <-chan *treetypes.Dev if err != nil { // ignore client-side cancellation (context closed) as it's expected when a client disconnects if dc.Context().Err() != nil || status.Code(err) == codes.Canceled { - log.V(logf.VDebug).Info("client context closed, skipping send", "client-identifier", clientIdentifier, "err", err) + log.V(logger.VDebug).Info("client context closed, skipping send", "client-identifier", clientIdentifier, "err", err) continue } log.Error(err, "error sending deviation", "client-identifier", clientIdentifier) diff --git a/pkg/datastore/target/gnmi/gnmi.go b/pkg/datastore/target/gnmi/gnmi.go index 9dccc65a..80032a04 100644 --- a/pkg/datastore/target/gnmi/gnmi.go +++ b/pkg/datastore/target/gnmi/gnmi.go @@ -30,7 +30,6 @@ import ( targetTypes "github.com/sdcio/data-server/pkg/datastore/target/types" "github.com/sdcio/data-server/pkg/pool" "github.com/sdcio/data-server/pkg/utils" - dsutils "github.com/sdcio/data-server/pkg/utils" logf "github.com/sdcio/logger" sdcpb "github.com/sdcio/sdc-protos/sdcpb" @@ -47,11 +46,11 @@ type gnmiTarget struct { cfg *config.SBI syncs map[string]GnmiSync runningStore targetTypes.RunningStore - schemaClient dsutils.SchemaClientBound + schemaClient utils.SchemaClientBound taskpoolFactory pool.VirtualPoolFactory } -func NewTarget(ctx context.Context, name string, cfg *config.SBI, runningStore targetTypes.RunningStore, schemaClient dsutils.SchemaClientBound, taskpoolFactory pool.VirtualPoolFactory, opts ...grpc.DialOption) (*gnmiTarget, error) { +func NewTarget(ctx context.Context, name string, cfg *config.SBI, runningStore targetTypes.RunningStore, schemaClient utils.SchemaClientBound, taskpoolFactory pool.VirtualPoolFactory, opts ...grpc.DialOption) (*gnmiTarget, error) { tc := &types.TargetConfig{ Name: name, Address: fmt.Sprintf("%s:%d", cfg.Address, cfg.Port), diff --git a/pkg/datastore/target/gnmi/stream.go b/pkg/datastore/target/gnmi/stream.go index 03da073a..46aaf328 100644 --- a/pkg/datastore/target/gnmi/stream.go +++ b/pkg/datastore/target/gnmi/stream.go @@ -3,6 +3,7 @@ package gnmi import ( "context" "errors" + "fmt" "sync" "time" @@ -209,7 +210,7 @@ func (s *StreamSync) gnmiSubscribe(subReq *gnmi.SubscribeRequest, updChan chan<- syncResponse <- struct{}{} case *gnmi.SubscribeResponse_Error: - log.Error(nil, "gnmi subscription error", "error", r.Error.Message) + log.Error(fmt.Errorf("%s", r.Error.Message), "gnmi subscription error") //nolint:staticcheck } } } diff --git a/pkg/datastore/target/netconf/nc.go b/pkg/datastore/target/netconf/nc.go index 1f77aa0f..44cd9ed0 100644 --- a/pkg/datastore/target/netconf/nc.go +++ b/pkg/datastore/target/netconf/nc.go @@ -130,7 +130,7 @@ func (t *ncTarget) internalGet(ctx context.Context, req *sdcpb.GetDataRequest) ( ncResponse, err := t.driver.GetConfig(source, filterDoc) if err != nil { if strings.Contains(err.Error(), "EOF") { - t.Close(ctx) + _ = t.Close(ctx) go t.reconnect(ctx) } return nil, err @@ -261,7 +261,7 @@ func (t *ncTarget) setToDevice(ctx context.Context, commitDatastore string, sour if err != nil { log.Error(err, "failed during edit-config") if strings.Contains(err.Error(), "EOF") { - t.Close(ctx) + _ = t.Close(ctx) go t.reconnect(ctx) return nil, err } @@ -288,7 +288,7 @@ func (t *ncTarget) setToDevice(ctx context.Context, commitDatastore string, sour err = t.driver.Commit() if err != nil { if strings.Contains(err.Error(), "EOF") { - t.Close(ctx) + _ = t.Close(ctx) go t.reconnect(ctx) } return nil, err diff --git a/pkg/datastore/target/netconf/nc_test.go b/pkg/datastore/target/netconf/nc_test.go index e426f397..1d963fe1 100644 --- a/pkg/datastore/target/netconf/nc_test.go +++ b/pkg/datastore/target/netconf/nc_test.go @@ -290,7 +290,7 @@ func TestLeafList(t *testing.T) { HonorNamespace: true, }) - xmlBuilder.AddValue(ctx, &sdcpb.Path{ + _ = xmlBuilder.AddValue(ctx, &sdcpb.Path{ Elem: []*sdcpb.PathElem{ { Name: "leaflist", @@ -367,7 +367,10 @@ func Test_filterRPCErrors(t *testing.T) { ` doc := etree.NewDocument() - doc.ReadFromString(xml) + err := doc.ReadFromString(xml) + if err != nil { + t.Error(err) + } type args struct { xml *etree.Document diff --git a/pkg/datastore/target/netconf/sync.go b/pkg/datastore/target/netconf/sync.go index 9bcb1526..3335cc64 100644 --- a/pkg/datastore/target/netconf/sync.go +++ b/pkg/datastore/target/netconf/sync.go @@ -70,7 +70,12 @@ func (s *NetconfSyncImpl) Start() error { return nil } - go s.internalSync(req) + go func() { + err := s.internalSync(req) + if err != nil { + log.Error(err, "failed syncing") + } + }() go func() { ticker := time.NewTicker(s.config.Interval) diff --git a/pkg/datastore/target/noop/noop.go b/pkg/datastore/target/noop/noop.go index a07a93b9..097b3b31 100644 --- a/pkg/datastore/target/noop/noop.go +++ b/pkg/datastore/target/noop/noop.go @@ -50,8 +50,8 @@ func (t *noopTarget) AddSyncs(ctx context.Context, sps ...*config.SyncProtocol) } func (t *noopTarget) Get(ctx context.Context, req *sdcpb.GetDataRequest) (*sdcpb.GetDataResponse, error) { - log := logf.FromContext(ctx).WithName("Get") - ctx = logf.IntoContext(ctx, log) + // log := logf.FromContext(ctx).WithName("Get") + // ctx = logf.IntoContext(ctx, log) result := &sdcpb.GetDataResponse{ Notification: make([]*sdcpb.Notification, 0, len(req.GetPath())), diff --git a/pkg/datastore/transaction_rpc.go b/pkg/datastore/transaction_rpc.go index 4cb07e20..bd539339 100644 --- a/pkg/datastore/transaction_rpc.go +++ b/pkg/datastore/transaction_rpc.go @@ -15,7 +15,6 @@ import ( treetypes "github.com/sdcio/data-server/pkg/tree/types" "github.com/sdcio/data-server/pkg/utils" "github.com/sdcio/logger" - logf "github.com/sdcio/logger" sdcpb "github.com/sdcio/sdc-protos/sdcpb" "github.com/sdcio/sdc-protos/tree_persist" "google.golang.org/protobuf/encoding/protojson" @@ -66,8 +65,8 @@ func (d *Datastore) SdcpbTransactionIntentToInternalTI(ctx context.Context, req // replaceIntent takes a Transaction and treats it as a replaceIntent, replacing the whole device configuration with the content of the given intent. // returns the warnings as a []string and potential errors that happend during validation / from SBI Set() func (d *Datastore) replaceIntent(ctx context.Context, transaction *types.Transaction) ([]string, error) { - log := logf.FromContext(ctx).WithValues("transaction-type", "replace") - ctx = logf.IntoContext(ctx, log) + log := logger.FromContext(ctx).WithValues("transaction-type", "replace") + ctx = logger.IntoContext(ctx, log) // create a new TreeContext tc := tree.NewTreeContext(d.schemaClient, d.Name()) @@ -101,14 +100,14 @@ func (d *Datastore) replaceIntent(ctx context.Context, transaction *types.Transa return nil, err } - log.V(logf.VDebug).Info("transaction finish tree insertion phase") + log.V(logger.VDebug).Info("transaction finish tree insertion phase") err = root.FinishInsertionPhase(ctx) if err != nil { return nil, err } // log the tree in trace level, making it a func call to spare overhead in lower log levels. - log.V(logf.VTrace).Info("populated tree", "tree", root.String()) + log.V(logger.VTrace).Info("populated tree", "tree", root.String()) // perform validation validationResult, validationStats := root.Validate(ctx, d.config.Validation, d.taskPool) @@ -148,7 +147,7 @@ func (d *Datastore) replaceIntent(ctx context.Context, transaction *types.Transa } func (d *Datastore) LoadAllButRunningIntents(ctx context.Context, root *tree.RootEntry, excludeDeviations bool) ([]string, error) { - log := logf.FromContext(ctx) + log := logger.FromContext(ctx) intentNames := []string{} IntentChan := make(chan *tree_persist.Intent) @@ -177,8 +176,8 @@ func (d *Datastore) LoadAllButRunningIntents(ctx context.Context, root *tree.Roo if excludeDeviations && intent.Deviation { continue } - log.V(logf.VDebug).Info("adding intent to tree", "intent", intent.GetIntentName()) - log.V(logf.VTrace).Info("adding intent to tree", "intent", intent.GetIntentName(), "content", utils.FormatProtoJSON(intent)) + log.V(logger.VDebug).Info("adding intent to tree", "intent", intent.GetIntentName()) + log.V(logger.VTrace).Info("adding intent to tree", "intent", intent.GetIntentName(), "content", utils.FormatProtoJSON(intent)) intentNames = append(intentNames, intent.GetIntentName()) protoLoader := treeproto.NewProtoTreeImporter(intent) @@ -195,7 +194,7 @@ func (d *Datastore) LoadAllButRunningIntents(ctx context.Context, root *tree.Roo // lowlevelTransactionSet func (d *Datastore) lowlevelTransactionSet(ctx context.Context, transaction *types.Transaction, dryRun bool) (*sdcpb.TransactionSetResponse, error) { - log := logf.FromContext(ctx) + log := logger.FromContext(ctx) // create a new TreeRoot d.syncTreeMutex.RLock() root, err := d.syncTree.DeepCopy(ctx) @@ -261,19 +260,19 @@ func (d *Datastore) lowlevelTransactionSet(ctx context.Context, transaction *typ transaction.GetOldRunning().AddUpdates(les.ToPathAndUpdateSlice()) - log.V(logf.VDebug).Info("transaction finish tree insertion phase") + log.V(logger.VDebug).Info("transaction finish tree insertion phase") // FinishInsertion Phase err = root.FinishInsertionPhase(ctx) if err != nil { return nil, err } - log.V(logf.VTrace).Info("populated tree", "tree", root.String()) + log.V(logger.VTrace).Info("populated tree", "tree", root.String()) // perform validation validationResult, validationStats := root.Validate(ctx, d.config.Validation, d.taskPool) - log.V(logf.VDebug).Info("transaction validation stats", "transaction-id", transaction.GetTransactionId(), "stats", validationStats.String()) + log.V(logger.VDebug).Info("transaction validation stats", "transaction-id", transaction.GetTransactionId(), "stats", validationStats.String()) // prepare the response struct result := &sdcpb.TransactionSetResponse{ @@ -338,8 +337,8 @@ func (d *Datastore) lowlevelTransactionSet(ctx context.Context, transaction *typ // logging updStrSl := treetypes.Map(updates.ToUpdateSlice(), func(u *treetypes.Update) string { return u.String() }) - log.V(logf.VTrace).Info("generated updates", "updates", strings.Join(updStrSl, "\n")) - log.V(logf.VTrace).Info("generated deletes", "deletes", strings.Join(deletes.SdcpbPaths().ToXPathSlice(), "\n")) + log.V(logger.VTrace).Info("generated updates", "updates", strings.Join(updStrSl, "\n")) + log.V(logger.VTrace).Info("generated deletes", "deletes", strings.Join(deletes.SdcpbPaths().ToXPathSlice(), "\n")) for _, intent := range transaction.GetNewIntents() { log := log.WithValues("intent", intent.GetName()) @@ -349,10 +348,10 @@ func (d *Datastore) lowlevelTransactionSet(ctx context.Context, transaction *typ // logging strSl := treetypes.Map(updatesOwner, func(u *treetypes.Update) string { return u.String() }) - log.V(logf.VTrace).Info("updates owner", "updates-owner", strSl) + log.V(logger.VTrace).Info("updates owner", "updates-owner", strSl) delSl := deletesOwner.ToXPathSlice() - log.V(logf.VTrace).Info("deletes owner", "deletes-owner", delSl) + log.V(logger.VTrace).Info("deletes owner", "deletes-owner", delSl) protoIntent, err := root.TreeExport(intent.GetName(), intent.GetPriority(), intent.Deviation()) switch { @@ -361,7 +360,7 @@ func (d *Datastore) lowlevelTransactionSet(ctx context.Context, transaction *typ if err != nil { log.Error(err, "failed deleting intent from store") } - log.V(logf.VDebug).Info("delete intent from cache") + log.V(logger.VDebug).Info("delete intent from cache") continue case err != nil: return nil, err @@ -444,7 +443,7 @@ func (d *Datastore) writeBackSyncTree(ctx context.Context, updates tree.LeafVari } func (d *Datastore) TransactionSet(ctx context.Context, transactionId string, transactionIntents []*types.TransactionIntent, replaceIntent *types.TransactionIntent, transactionTimeout time.Duration, dryRun bool) (*sdcpb.TransactionSetResponse, error) { - log := logf.FromContext(ctx) + log := logger.FromContext(ctx) var err error var transaction *types.Transaction var transactionGuard *types.TransactionGuard @@ -554,7 +553,7 @@ func updateToSdcpbUpdate(lvs tree.LeafVariantSlice) ([]*sdcpb.Update, error) { } func (d *Datastore) TransactionConfirm(ctx context.Context, transactionId string) error { - log := logf.FromContext(ctx) + log := logger.FromContext(ctx) log.Info("transaction confirm") if !d.dmutex.TryLock() { @@ -566,7 +565,7 @@ func (d *Datastore) TransactionConfirm(ctx context.Context, transactionId string } func (d *Datastore) TransactionCancel(ctx context.Context, transactionId string) error { - log := logf.FromContext(ctx) + log := logger.FromContext(ctx) log.Info("transaction cancel") if !d.dmutex.TryLock() { diff --git a/pkg/datastore/types/transaction.go b/pkg/datastore/types/transaction.go index 0b80ea25..90679b12 100644 --- a/pkg/datastore/types/transaction.go +++ b/pkg/datastore/types/transaction.go @@ -7,6 +7,7 @@ import ( "github.com/sdcio/data-server/pkg/tree" treetypes "github.com/sdcio/data-server/pkg/tree/types" + "github.com/sdcio/logger" sdcpb "github.com/sdcio/sdc-protos/sdcpb" ) @@ -63,7 +64,9 @@ func (t *Transaction) Confirm() error { func (t *Transaction) rollback(ctx context.Context) func() { return func() { - t.transactionManager.Rollback(ctx, t.GetRollbackTransaction()) + log := logger.FromContext(ctx) + err := t.transactionManager.Rollback(ctx, t.GetRollbackTransaction(ctx)) + log.Error(err, "rollback failed") } } @@ -90,11 +93,15 @@ func (t *Transaction) IntentCount() int { return len(t.newIntents) } -func (t *Transaction) GetRollbackTransaction() *Transaction { +func (t *Transaction) GetRollbackTransaction(ctx context.Context) *Transaction { t.timer.Stop() tr := NewTransaction(t.GetTransactionId()+" - Rollback", t.transactionManager) for _, v := range t.oldIntents { - tr.AddTransactionIntent(v, TransactionIntentNew) + err := tr.AddTransactionIntent(v, TransactionIntentNew) + if err != nil { + log := logger.FromContext(ctx) + log.Error(err, "failed getting rollback transaction", "intent", v.name) + } } tr.isRollback = true return tr diff --git a/pkg/datastore/types/transaction_manager.go b/pkg/datastore/types/transaction_manager.go index 5d13a1f0..a7d5ae37 100644 --- a/pkg/datastore/types/transaction_manager.go +++ b/pkg/datastore/types/transaction_manager.go @@ -80,7 +80,7 @@ func (t *TransactionManager) Cancel(ctx context.Context, id string) error { if t.transaction == nil { return fmt.Errorf("no ongoing transaction") } - rollbacktransAction := t.transaction.GetRollbackTransaction() + rollbacktransAction := t.transaction.GetRollbackTransaction(ctx) _, err := t.rollbacker.TransactionRollback(ctx, rollbacktransAction, false) if err != nil { diff --git a/pkg/pool/virtual_pool.go b/pkg/pool/virtual_pool.go index 850f4124..9d328a4e 100644 --- a/pkg/pool/virtual_pool.go +++ b/pkg/pool/virtual_pool.go @@ -105,8 +105,6 @@ const ( // creation of VirtualPools that submit into the shared pool. type SharedTaskPool struct { inner *Pool[Task] - - mu sync.RWMutex } // NewSharedTaskPool constructs a shared pool; caller should call Start() to begin workers. diff --git a/pkg/pool/virtual_pool_test.go b/pkg/pool/virtual_pool_test.go index 086abc2c..b7ffd0dc 100644 --- a/pkg/pool/virtual_pool_test.go +++ b/pkg/pool/virtual_pool_test.go @@ -213,14 +213,14 @@ func TestVirtualPool_CancellationHang(t *testing.T) { wg.Add(2) // Task 1: blocks until cancelled - vp.SubmitFunc(func(ctx context.Context, submit func(Task) error) error { + _ = vp.SubmitFunc(func(ctx context.Context, submit func(Task) error) error { defer wg.Done() <-ctx.Done() return nil }) // Task 2: should run even if cancelled (to decrement inflight) - vp.SubmitFunc(func(ctx context.Context, submit func(Task) error) error { + _ = vp.SubmitFunc(func(ctx context.Context, submit func(Task) error) error { defer wg.Done() return nil }) diff --git a/pkg/server/datastore.go b/pkg/server/datastore.go index de1b3550..c44ae661 100644 --- a/pkg/server/datastore.go +++ b/pkg/server/datastore.go @@ -26,7 +26,6 @@ import ( targettypes "github.com/sdcio/data-server/pkg/datastore/target/types" "github.com/sdcio/data-server/pkg/utils" "github.com/sdcio/logger" - logf "github.com/sdcio/logger" sdcpb "github.com/sdcio/sdc-protos/sdcpb" "google.golang.org/grpc/codes" "google.golang.org/grpc/peer" @@ -35,10 +34,10 @@ import ( // datastore func (s *Server) ListDataStore(ctx context.Context, req *sdcpb.ListDataStoreRequest) (*sdcpb.ListDataStoreResponse, error) { - log := logf.FromContext(ctx).WithName("ListDataStore") - ctx = logf.IntoContext(ctx, log) + log := logger.FromContext(ctx).WithName("ListDataStore") + ctx = logger.IntoContext(ctx, log) - log.V(logf.VDebug).Info("received request", "raw-request", utils.FormatProtoJSON(req)) + log.V(logger.VDebug).Info("received request", "raw-request", utils.FormatProtoJSON(req)) datastores := s.datastores.GetDatastoreAll() rs := make([]*sdcpb.GetDataStoreResponse, 0, len(datastores)) @@ -55,13 +54,13 @@ func (s *Server) ListDataStore(ctx context.Context, req *sdcpb.ListDataStoreRequ } func (s *Server) GetDataStore(ctx context.Context, req *sdcpb.GetDataStoreRequest) (*sdcpb.GetDataStoreResponse, error) { - log := logf.FromContext(ctx).WithName("GetDataStore") + log := logger.FromContext(ctx).WithName("GetDataStore") log = log.WithValues( "datastore-name", req.GetDatastoreName(), ) - ctx = logf.IntoContext(ctx, log) + ctx = logger.IntoContext(ctx, log) - log.V(logf.VDebug).Info("received request", "raw-request", utils.FormatProtoJSON(req)) + log.V(logger.VDebug).Info("received request", "raw-request", utils.FormatProtoJSON(req)) name := req.GetDatastoreName() if name == "" { return nil, status.Error(codes.InvalidArgument, "missing datastore name attribute") @@ -74,17 +73,17 @@ func (s *Server) GetDataStore(ctx context.Context, req *sdcpb.GetDataStoreReques } func (s *Server) CreateDataStore(ctx context.Context, req *sdcpb.CreateDataStoreRequest) (*sdcpb.CreateDataStoreResponse, error) { - log := logf.FromContext(ctx).WithName("CreateDataStore") + log := logger.FromContext(ctx).WithName("CreateDataStore") log = log.WithValues( "datastore-name", req.GetDatastoreName(), ) - ctx = logf.IntoContext(ctx, log) + // ctx = logger.IntoContext(ctx, log) log.Info("creating datastore", "datastore-schema", req.GetSchema(), "datastore-target", req.GetTarget(), ) - log.V(logf.VDebug).Info("received request", "raw-request", utils.FormatProtoJSON(req)) + log.V(logger.VDebug).Info("received request", "raw-request", utils.FormatProtoJSON(req)) name := req.GetDatastoreName() lName := len(name) @@ -222,10 +221,10 @@ func (s *Server) CreateDataStore(ctx context.Context, req *sdcpb.CreateDataStore } func (s *Server) DeleteDataStore(ctx context.Context, req *sdcpb.DeleteDataStoreRequest) (*sdcpb.DeleteDataStoreResponse, error) { - log := logf.FromContext(ctx).WithName("DeleteDataStore") - ctx = logf.IntoContext(ctx, log) + log := logger.FromContext(ctx).WithName("DeleteDataStore") + ctx = logger.IntoContext(ctx, log) - log.V(logf.VDebug).Info("received request", "raw-request", utils.FormatProtoJSON(req)) + log.V(logger.VDebug).Info("received request", "raw-request", utils.FormatProtoJSON(req)) name := req.GetName() if name == "" { @@ -258,10 +257,10 @@ func (s *Server) WatchDeviations(req *sdcpb.WatchDeviationRequest, stream sdcpb. if ok { peerName = p.Addr.String() } - log := logf.FromContext(ctx).WithName("WatchDeviations").WithValues("peer", peerName) - ctx = logf.IntoContext(ctx, log) + log := logger.FromContext(ctx).WithName("WatchDeviations").WithValues("peer", peerName) + ctx = logger.IntoContext(ctx, log) - log.V(logf.VDebug).Info("received request", "raw-request", utils.FormatProtoJSON(req)) + log.V(logger.VDebug).Info("received request", "raw-request", utils.FormatProtoJSON(req)) if !ok { return status.Errorf(codes.InvalidArgument, "missing peer info") @@ -324,10 +323,10 @@ func (s *Server) datastoreToRsp(ctx context.Context, ds *datastore.Datastore) (* } func (s *Server) BlameConfig(ctx context.Context, req *sdcpb.BlameConfigRequest) (*sdcpb.BlameConfigResponse, error) { - log := logf.FromContext(ctx).WithName("BlameConfig") - ctx = logf.IntoContext(ctx, log) + log := logger.FromContext(ctx).WithName("BlameConfig") + ctx = logger.IntoContext(ctx, log) - log.V(logf.VDebug).Info("received request", "raw-request", utils.FormatProtoJSON(req)) + log.V(logger.VDebug).Info("received request", "raw-request", utils.FormatProtoJSON(req)) if req.GetDatastoreName() == "" { return nil, status.Errorf(codes.InvalidArgument, "missing datastore name") diff --git a/pkg/server/schema.go b/pkg/server/schema.go index e521c898..561bb052 100644 --- a/pkg/server/schema.go +++ b/pkg/server/schema.go @@ -101,7 +101,7 @@ func (s *Server) createRemoteSchemaClient(ctx context.Context) { log := logf.FromContext(ctx) SCHEMA_CONNECT: opts := []grpc.DialOption{ - grpc.WithBlock(), + grpc.WithBlock(), //nolint:staticcheck } switch s.config.SchemaServer.TLS { case nil: @@ -126,7 +126,7 @@ SCHEMA_CONNECT: dialCtx, cancel := context.WithTimeout(ctx, schemaServerConnectRetry) defer cancel() - cc, err := grpc.DialContext(dialCtx, s.config.SchemaServer.Address, opts...) + cc, err := grpc.DialContext(dialCtx, s.config.SchemaServer.Address, opts...) //nolint:staticcheck if err != nil { log.Error(err, "failed to connect to schema server") time.Sleep(time.Second) diff --git a/pkg/server/server.go b/pkg/server/server.go index 2e48bf48..5251b6f4 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -29,7 +29,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promhttp" - logf "github.com/sdcio/logger" + "github.com/sdcio/logger" sdcpb "github.com/sdcio/sdc-protos/sdcpb" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -81,8 +81,10 @@ func NewDatastoreMap() *DatastoreMap { } } func (d *DatastoreMap) StopAll(ctx context.Context) { + log := logger.FromContext(ctx) for _, ds := range d.datastores { - ds.Stop(ctx) + err := ds.Stop(ctx) + log.Error(err, "stopping datastore failed", "datastore-name", ds.Name()) } } @@ -98,13 +100,17 @@ func (d *DatastoreMap) AddDatastore(ds *datastore.Datastore) error { } func (d *DatastoreMap) DeleteDatastore(ctx context.Context, name string) error { + log := logger.FromContext(ctx) d.md.Lock() defer d.md.Unlock() ds, err := d.getDataStore(name) if err != nil { return err } - ds.Delete(ctx) + err = ds.Delete(ctx) + if err != nil { + log.Error(err, "delete datastore failed", "datastore-name", ds.Name()) + } delete(d.datastores, name) return nil } @@ -209,7 +215,7 @@ func New(ctx context.Context, c *config.Config) (*Server, error) { } func (s *Server) Serve(ctx context.Context) error { - log := logf.FromContext(ctx) + log := logger.FromContext(ctx) l, err := net.Listen("tcp", s.config.GRPCServer.Address) if err != nil { return err @@ -231,7 +237,7 @@ func (s *Server) Serve(ctx context.Context) error { } func (s *Server) ServeHTTP(ctx context.Context) { - log := logf.FromContext(ctx) + log := logger.FromContext(ctx) s.router.Handle("/metrics", promhttp.HandlerFor(s.reg, promhttp.HandlerOpts{})) s.reg.MustRegister(collectors.NewGoCollector()) s.reg.MustRegister(collectors.NewProcessCollector(collectors.ProcessCollectorOpts{})) @@ -254,7 +260,7 @@ func (s *Server) Stop() { } func (s *Server) startDataServer(ctx context.Context) { - log := logf.FromContext(ctx) + log := logger.FromContext(ctx) wg := new(sync.WaitGroup) wg.Add(2) @@ -278,7 +284,7 @@ func (s *Server) startDataServer(ctx context.Context) { } func (s *Server) createInitialDatastores(ctx context.Context) { - log := logf.FromContext(ctx) + log := logger.FromContext(ctx) numConfiguredDS := len(s.config.Datastores) if numConfiguredDS == 0 { return @@ -287,7 +293,7 @@ func (s *Server) createInitialDatastores(ctx context.Context) { wg.Add(numConfiguredDS) for _, dsCfg := range s.config.Datastores { - log.V(logf.VDebug).Info("creating datastore", "datastore-name", dsCfg.Name) + log.V(logger.VDebug).Info("creating datastore", "datastore-name", dsCfg.Name) dsCfg.Validation = s.config.Validation.DeepCopy() go func(dsCfg *config.DatastoreConfig) { defer wg.Done() @@ -322,8 +328,8 @@ func (s *Server) readyInterceptor(ctx context.Context, req interface{}, info *gr func contextLoggingInterceptor(logCtx context.Context) func(context.Context, interface{}, *grpc.UnaryServerInfo, grpc.UnaryHandler) (resp interface{}, err error) { return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { uuidString := uuid.New().String() - log := logf.FromContext(logCtx).WithValues("grpc-request-uuid", uuidString) - ctx = logf.IntoContext(ctx, log) + log := logger.FromContext(logCtx).WithValues("grpc-request-uuid", uuidString) + ctx = logger.IntoContext(ctx, log) return handler(ctx, req) } @@ -332,9 +338,9 @@ func contextLoggingInterceptor(logCtx context.Context) func(context.Context, int func contextLoggingServerStreamInterceptor(ctx context.Context) func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { uuidString := uuid.New().String() - log := logf.FromContext(ctx).WithValues("grpc-request-uuid", uuidString) + log := logger.FromContext(ctx).WithValues("grpc-request-uuid", uuidString) wss := grpc_middleware.WrapServerStream(ss) - wss.WrappedContext = logf.IntoContext(wss.WrappedContext, log) + wss.WrappedContext = logger.IntoContext(wss.WrappedContext, log) return handler(srv, wss) } diff --git a/pkg/tree/json.go b/pkg/tree/json.go index 23abe03b..0fa079e6 100644 --- a/pkg/tree/json.go +++ b/pkg/tree/json.go @@ -93,7 +93,7 @@ func (s *sharedEntryAttributes) toJsonInternal(onlyNewOrUpdated bool, ietf bool) return nil, nil } le := s.leafVariants.GetHighestPrecedence(false, false, false) - if le == nil || onlyNewOrUpdated && !(le.IsNew || le.IsUpdated) { + if le == nil || onlyNewOrUpdated && !le.IsNew && !le.IsUpdated { return nil, nil } } @@ -151,7 +151,7 @@ func jsonAddKeyElements(s Entry, dict map[string]any) { parentSchema, levelsUp := s.GetFirstAncestorWithSchema() // from the parent we get the keys as slice schemaKeys := parentSchema.GetSchemaKeys() - var treeElem Entry = s + treeElem := s // the keys do match the levels up in the tree in reverse order // hence we init i with levelUp and count down for i := levelsUp - 1; i >= 0; i-- { diff --git a/pkg/tree/leaf_entry.go b/pkg/tree/leaf_entry.go index 30856fb1..9d4952a8 100644 --- a/pkg/tree/leaf_entry.go +++ b/pkg/tree/leaf_entry.go @@ -148,7 +148,7 @@ func (l *LeafEntry) Compare(other *LeafEntry) int { if result != 0 { return result } - return strings.Compare(l.Update.Owner(), other.Update.Owner()) + return strings.Compare(l.Owner(), other.Owner()) } // NewLeafEntry constructor for a new LeafEntry diff --git a/pkg/tree/leaf_variants.go b/pkg/tree/leaf_variants.go index e7d0d7ef..10661094 100644 --- a/pkg/tree/leaf_variants.go +++ b/pkg/tree/leaf_variants.go @@ -78,7 +78,7 @@ func (lv *LeafVariants) canDeleteBranch(keepDefault bool) bool { // go through all variants for _, l := range lv.les { // if the LeafVariant is not owned by running or default - if l.Update.Owner() != DefaultsIntentName || keepDefault { + if l.Owner() != DefaultsIntentName || keepDefault { // then we need to check that it remains, so not Delete Flag set or DeleteOnylIntended Flags set [which results in not doing a delete towards the device] if l.GetDeleteOnlyIntendedFlag() || !l.GetDeleteFlag() { // then this entry should not be deleted @@ -112,7 +112,7 @@ func (lv *LeafVariants) canDelete() bool { // go through all variants for _, l := range lv.les { // if the LeafVariant is not owned by running or default - if l.Update.Owner() != RunningIntentName && l.Update.Owner() != DefaultsIntentName && !l.IsExplicitDelete { + if l.Owner() != RunningIntentName && l.Owner() != DefaultsIntentName && !l.IsExplicitDelete { // then we need to check that it remains, so not Delete Flag set or DeleteOnylIntended Flags set [which results in not doing a delete towards the device] if l.GetDeleteOnlyIntendedFlag() || !l.GetDeleteFlag() { // then this entry should not be deleted @@ -149,7 +149,7 @@ func (lv *LeafVariants) shouldDelete() bool { // go through all variants for _, l := range lv.les { // if an entry exists that is not owned by running or default, - if l.Update.Owner() == RunningIntentName || l.Update.Owner() == DefaultsIntentName { + if l.Owner() == RunningIntentName || l.Owner() == DefaultsIntentName { continue } foundOtherThenRunningAndDefault = true @@ -205,8 +205,8 @@ func (lv *LeafVariants) GetHighestPrecedenceValue(filter HighestPrecedenceFilter defer lv.lesMutex.RUnlock() result := int32(math.MaxInt32) for _, e := range lv.les { - if filter(e) && e.Owner() != DefaultsIntentName && e.Update.Priority() < result { - result = e.Update.Priority() + if filter(e) && e.Owner() != DefaultsIntentName && e.Priority() < result { + result = e.Priority() } } return result @@ -231,7 +231,7 @@ func (lv *LeafVariants) DeepCopy(tc *TreeContext, parent Entry) *LeafVariants { // checkReturnDefault checks if defaults are allowed and if the given LeafEntry is owned by default func checkNotDefaultAllowedButIsDefaultOwner(le *LeafEntry, includeDefaults bool) bool { - return !includeDefaults && le.Update.Owner() == DefaultsIntentName + return !includeDefaults && le.Owner() == DefaultsIntentName } func checkExistsAndDeleteFlagSet(le *LeafEntry) bool { @@ -250,7 +250,7 @@ func (lv *LeafVariants) GetRunning() *LeafEntry { lv.lesMutex.RLock() defer lv.lesMutex.RUnlock() for _, e := range lv.les { - if e.Update.Owner() == RunningIntentName { + if e.Owner() == RunningIntentName { return e } } @@ -327,7 +327,7 @@ func (lv *LeafVariants) highestIsUnequalRunning(highest *LeafEntry) bool { lv.lesMutex.RLock() defer lv.lesMutex.RUnlock() // if highes is already running or even default, return false - if highest.Update.Owner() == RunningIntentName { + if highest.Owner() == RunningIntentName { return false } diff --git a/pkg/tree/parallelImporter.go b/pkg/tree/parallelImporter.go index 83f7ee2d..a11e96c8 100644 --- a/pkg/tree/parallelImporter.go +++ b/pkg/tree/parallelImporter.go @@ -56,8 +56,8 @@ func importHandler(ctx context.Context, task importTask, submit func(importTask) // keyed container: handle keys sequentially if len(task.entry.GetSchema().GetContainer().GetKeys()) > 0 { var exists bool - var actual Entry = task.entry var keyChild Entry + actual := task.entry keys := task.entry.GetSchemaKeys() slices.Sort(keys) diff --git a/pkg/tree/processor_blame_config.go b/pkg/tree/processor_blame_config.go index 90063420..e7f03389 100644 --- a/pkg/tree/processor_blame_config.go +++ b/pkg/tree/processor_blame_config.go @@ -89,13 +89,13 @@ func (t *BlameConfigTask) Run(ctx context.Context, submit func(pool.Task) error) // process Value highestLe := t.selfEntry.GetLeafVariantEntries().GetHighestPrecedence(false, true, true) if highestLe != nil { - if highestLe.Update.Owner() != DefaultsIntentName || t.config.includeDefaults { - t.self.SetValue(highestLe.Update.Value()).SetOwner(highestLe.Update.Owner()) + if highestLe.Owner() != DefaultsIntentName || t.config.includeDefaults { + t.self.SetValue(highestLe.Value()).SetOwner(highestLe.Owner()) // check if running equals the expected runningLe := t.selfEntry.GetLeafVariantEntries().GetRunning() if runningLe != nil { - if !proto.Equal(runningLe.Update.Value(), highestLe.Update.Value()) { + if !proto.Equal(runningLe.Value(), highestLe.Value()) { t.self.SetDeviationValue(runningLe.Value()) } } diff --git a/pkg/tree/processor_mark_owner_delete.go b/pkg/tree/processor_mark_owner_delete.go index 2dcf5c49..c0e38447 100644 --- a/pkg/tree/processor_mark_owner_delete.go +++ b/pkg/tree/processor_mark_owner_delete.go @@ -68,7 +68,10 @@ func (x ownerDeleteMarkerTask) Run(ctx context.Context, submit func(pool.Task) e x.matches.Append(le) } for _, c := range x.e.GetChilds(DescendMethodAll) { - submit(newOwnerDeleteMarkerTask(x.config, c, x.matches)) + err := submit(newOwnerDeleteMarkerTask(x.config, c, x.matches)) + if err != nil { + return err + } } return nil } diff --git a/pkg/tree/processor_validate.go b/pkg/tree/processor_validate.go index a8a018c5..365afe57 100644 --- a/pkg/tree/processor_validate.go +++ b/pkg/tree/processor_validate.go @@ -18,11 +18,12 @@ func NewValidateProcessor(parameters *ValidateProcessorParameters) *ValidateProc } } -func (p *ValidateProcessor) Run(taskpoolFactory pool.VirtualPoolFactory, e Entry) { +func (p *ValidateProcessor) Run(taskpoolFactory pool.VirtualPoolFactory, e Entry) error { taskpool := taskpoolFactory.NewVirtualPool(pool.VirtualTolerant, 0) - taskpool.Submit(newValidateTask(e, p.parameters)) + err := taskpool.Submit(newValidateTask(e, p.parameters)) taskpool.CloseForSubmit() taskpool.Wait() + return err } type ValidateProcessorParameters struct { @@ -59,7 +60,10 @@ func (t *validateTask) Run(ctx context.Context, submit func(pool.Task) error) er if t.e.remainsToExist() { t.e.ValidateLevel(ctx, t.parameters.resultChan, t.parameters.stats, t.parameters.vCfg) for _, c := range t.e.GetChilds(DescendMethodActiveChilds) { - submit(newValidateTask(c, t.parameters)) + err := submit(newValidateTask(c, t.parameters)) + if err != nil { + return err + } } } return nil diff --git a/pkg/tree/root_entry.go b/pkg/tree/root_entry.go index 8eea8a8f..54c94f0b 100644 --- a/pkg/tree/root_entry.go +++ b/pkg/tree/root_entry.go @@ -12,7 +12,7 @@ import ( "github.com/sdcio/data-server/pkg/tree/importer" "github.com/sdcio/data-server/pkg/tree/types" "github.com/sdcio/data-server/pkg/utils" - logf "github.com/sdcio/logger" + "github.com/sdcio/logger" sdcpb "github.com/sdcio/sdc-protos/sdcpb" "github.com/sdcio/sdc-protos/tree_persist" ) @@ -48,14 +48,14 @@ func NewTreeRoot(ctx context.Context, tc *TreeContext) (*RootEntry, error) { } // stringToDisk just for debugging purpose -func (r *RootEntry) stringToDisk(filename string) error { +func (r *RootEntry) stringToDisk(filename string) error { // nolint:unused err := os.WriteFile(filename, []byte(r.String()), 0755) return err } func (r *RootEntry) DeepCopy(ctx context.Context) (*RootEntry, error) { tc := r.treeContext.deepCopy() - se, err := r.sharedEntryAttributes.deepCopy(tc, nil) + se, err := r.deepCopy(tc, nil) if err != nil { return nil, err } @@ -80,7 +80,7 @@ func (r *RootEntry) AddUpdatesRecursive(ctx context.Context, us []*types.PathAnd var err error for idx, u := range us { _ = idx - _, err = r.sharedEntryAttributes.AddUpdateRecursive(ctx, u.GetPath(), u.GetUpdate(), flags) + _, err = r.AddUpdateRecursive(ctx, u.GetPath(), u.GetUpdate(), flags) if err != nil { return err } @@ -91,7 +91,7 @@ func (r *RootEntry) AddUpdatesRecursive(ctx context.Context, us []*types.PathAnd func (r *RootEntry) ImportConfig(ctx context.Context, basePath *sdcpb.Path, importer importer.ImportConfigAdapter, intentName string, intentPrio int32, flags *types.UpdateInsertFlags) error { r.treeContext.SetActualOwner(intentName) - e, err := r.sharedEntryAttributes.getOrCreateChilds(ctx, basePath) + e, err := r.getOrCreateChilds(ctx, basePath) if err != nil { return err } @@ -119,13 +119,17 @@ func (r *RootEntry) Validate(ctx context.Context, vCfg *config.Validation, taskp go func() { // read from the validationResult channel for e := range validationResultEntryChan { - validationResult.AddEntry(e) + err := validationResult.AddEntry(e) + if err != nil { + log := logger.FromContext(ctx) + log.Error(err, "adding validation result failed") + } } syncWait.Done() }() validationProcessor := NewValidateProcessor(NewValidateProcessorConfig(validationResultEntryChan, validationStats, vCfg)) - validationProcessor.Run(taskpoolFactory, r.sharedEntryAttributes) + _ = validationProcessor.Run(taskpoolFactory, r.sharedEntryAttributes) close(validationResultEntryChan) syncWait.Wait() @@ -135,7 +139,7 @@ func (r *RootEntry) Validate(ctx context.Context, vCfg *config.Validation, taskp // String returns the string representation of the Tree. func (r *RootEntry) String() string { s := []string{} - s = r.sharedEntryAttributes.StringIndent(s) + s = r.StringIndent(s) return strings.Join(s, "\n") } @@ -214,7 +218,7 @@ func (r *RootEntry) TreeExport(owner string, priority int32, deviation bool) (*t func (r *RootEntry) getByOwnerFiltered(owner string, f ...LeafEntryFilter) []*LeafEntry { result := []*LeafEntry{} // retrieve all leafentries for the owner - leafEntries := r.sharedEntryAttributes.GetByOwner(owner, result) + leafEntries := r.GetByOwner(owner, result) // range through entries NEXTELEMENT: for _, e := range leafEntries { @@ -242,7 +246,7 @@ func (r *RootEntry) DeleteBranchPaths(ctx context.Context, deletes types.DeleteE } func (r *RootEntry) FinishInsertionPhase(ctx context.Context) error { - log := logf.FromContext(ctx) + log := logger.FromContext(ctx) edvs := ExplicitDeleteVisitors{} // apply the explicit deletes @@ -265,7 +269,7 @@ func (r *RootEntry) FinishInsertionPhase(ctx context.Context) error { edvs[deletePathPrio.GetOwner()] = edv } } - log.V(logf.VDebug).Info("ExplicitDeletes added", "explicit-deletes", utils.MapToString(edvs.Stats(), ", ", func(k string, v int) string { + log.V(logger.VDebug).Info("ExplicitDeletes added", "explicit-deletes", utils.MapToString(edvs.Stats(), ", ", func(k string, v int) string { return fmt.Sprintf("%s=%d", k, v) })) diff --git a/pkg/tree/sharedEntryAttributes.go b/pkg/tree/sharedEntryAttributes.go index d8025333..5a7b66ec 100644 --- a/pkg/tree/sharedEntryAttributes.go +++ b/pkg/tree/sharedEntryAttributes.go @@ -22,7 +22,7 @@ import ( ) var ( - ValidationError = errors.New("validation error") + ErrValidation = errors.New("validation error") ) // sharedEntryAttributes contains the attributes shared by Entry and RootEntry @@ -171,13 +171,10 @@ func (s *sharedEntryAttributes) loadDefaults(ctx context.Context) error { } func (s *sharedEntryAttributes) GetDeviations(ctx context.Context, ch chan<- *types.DeviationEntry, activeCase bool) { - evalLeafvariants := true // if s is a presence container but has active childs, it should not be treated as a presence // container, hence the leafvariants should not be processed. For presence container with // childs the TypedValue.empty_val in the presence container is irrelevant. - if s.schema.GetContainer().GetIsPresence() && len(s.GetChilds(DescendMethodActiveChilds)) > 0 { - evalLeafvariants = false - } + evalLeafvariants := !s.schema.GetContainer().GetIsPresence() || len(s.GetChilds(DescendMethodActiveChilds)) == 0 if evalLeafvariants { // calculate Deviation on the LeafVariants @@ -766,7 +763,7 @@ func (s *sharedEntryAttributes) NavigateSdcpbPath(ctx context.Context, path *sdc switch pathElems[0].Name { case ".": - s.NavigateSdcpbPath(ctx, path.CopyAndRemoveFirstPathElem()) + return s.NavigateSdcpbPath(ctx, path.CopyAndRemoveFirstPathElem()) case "..": var entry Entry entry = s.parent @@ -801,8 +798,6 @@ func (s *sharedEntryAttributes) NavigateSdcpbPath(ctx context.Context, path *sdc return e.NavigateSdcpbPath(ctx, path.CopyAndRemoveFirstPathElem()) } - - return nil, fmt.Errorf("navigating tree, reached %v but child %v does not exist", s.SdcpbPath().ToXPath(false), pathElems) } func (s *sharedEntryAttributes) tryLoadingDefault(ctx context.Context, path *sdcpb.Path) (Entry, error) { @@ -1020,7 +1015,7 @@ func (s *sharedEntryAttributes) validateRange(resultChan chan<- *types.Validatio return } - tv := lv.Update.Value() + tv := lv.Value() var tvs []*sdcpb.TypedValue var typeSchema *sdcpb.SchemaLeafType @@ -1119,7 +1114,7 @@ func (s *sharedEntryAttributes) validateMinMaxElements(resultChan chan<- *types. if keyAttr, ok := childAttributes[keyName]; ok { highestPrec := keyAttr.GetHighestPrecedence(nil, false, false, false) if len(highestPrec) > 0 { - owner := highestPrec[0].Update.Owner() + owner := highestPrec[0].Owner() ownersSet[owner] = struct{}{} } } @@ -1148,7 +1143,7 @@ func (s *sharedEntryAttributes) validateLeafListMinMaxAttributes(resultChan chan if schema := s.schema.GetLeaflist(); schema != nil { if schema.GetMinElements() > 0 || schema.GetMaxElements() < math.MaxUint64 { if lv := s.leafVariants.GetHighestPrecedence(false, true, false); lv != nil { - tv := lv.Update.Value() + tv := lv.Value() if val := tv.GetLeaflistVal(); val != nil { // check minelements if set @@ -1260,7 +1255,7 @@ func (s *sharedEntryAttributes) validateMandatory(ctx context.Context, resultCha } if len(attributes) == 0 { - log.Error(ValidationError, "mandatory attribute could not be found as child, field or choice", "path", s.SdcpbPath().ToXPath(false), "attribute", c.Name) + log.Error(ErrValidation, "mandatory attribute could not be found as child, field or choice", "path", s.SdcpbPath().ToXPath(false), "attribute", c.Name) } s.validateMandatoryWithKeys(ctx, len(s.GetSchema().GetContainer().GetKeys()), attributes, choiceName, resultChan) diff --git a/pkg/tree/types/update_slice.go b/pkg/tree/types/update_slice.go index 0d108a82..368084a1 100644 --- a/pkg/tree/types/update_slice.go +++ b/pkg/tree/types/update_slice.go @@ -22,7 +22,7 @@ func (u UpdateSlice) CopyWithNewOwnerAndPrio(owner string, prio int32) []*PathAn func (u UpdateSlice) String() string { sb := &strings.Builder{} for i, j := range u { - sb.WriteString(fmt.Sprintf("%d - %s -> %s\n", i, j.Path().ToXPath(false), j.value.ToString())) + fmt.Fprintf(sb, "%d - %s -> %s\n", i, j.Path().ToXPath(false), j.value.ToString()) } return sb.String() } diff --git a/pkg/tree/types/validation_result.go b/pkg/tree/types/validation_result.go index bdffbb76..cac4cb75 100644 --- a/pkg/tree/types/validation_result.go +++ b/pkg/tree/types/validation_result.go @@ -67,7 +67,7 @@ func (v ValidationResults) JoinErrors() error { var result error for _, intent := range v { - errors.Join(result, errors.Join(intent.errors...)) + result = errors.Join(result, errors.Join(intent.errors...)) } return result } @@ -76,7 +76,7 @@ func (v ValidationResults) JoinWarnings() error { var result error for _, intent := range v { - errors.Join(result, errors.Join(intent.warnings...)) + result = errors.Join(result, errors.Join(intent.warnings...)) } return result } @@ -110,11 +110,11 @@ func (v *ValidationResultIntent) String() string { sb := &strings.Builder{} newLine := "" for _, e := range v.errors { - sb.WriteString(fmt.Sprintf("%s%s: %s - %s", newLine, v.intentName, "error", e.Error())) + fmt.Fprintf(sb, "%s%s: %s - %s", newLine, v.intentName, "error", e.Error()) newLine = "\n" } for _, e := range v.warnings { - sb.WriteString(fmt.Sprintf("%s%s: %s - %s", newLine, v.intentName, "warning", e.Error())) + fmt.Fprintf(sb, "%s%s: %s - %s", newLine, v.intentName, "warning", e.Error()) newLine = "\n" } return sb.String() diff --git a/pkg/tree/visitor_explicit_delete_test.go b/pkg/tree/visitor_explicit_delete_test.go index 172b44cb..71da74b5 100644 --- a/pkg/tree/visitor_explicit_delete_test.go +++ b/pkg/tree/visitor_explicit_delete_test.go @@ -143,7 +143,7 @@ func TestExplicitDeleteVisitor_Visit(t *testing.T) { t.Error(err) } - testhelper.LoadYgotStructIntoTreeRoot(ctx, &sdcio_schema.Device{Interface: map[string]*sdcio_schema.SdcioModel_Interface{ + _ = testhelper.LoadYgotStructIntoTreeRoot(ctx, &sdcio_schema.Device{Interface: map[string]*sdcio_schema.SdcioModel_Interface{ "ethernet-1/1": { Name: ygot.String("ethernet-1/1"), Description: ygot.String("mydesc"), diff --git a/pkg/tree/xml.go b/pkg/tree/xml.go index f71b4804..0f33458f 100644 --- a/pkg/tree/xml.go +++ b/pkg/tree/xml.go @@ -146,7 +146,7 @@ func (s *sharedEntryAttributes) toXmlInternal(parent *etree.Element, onlyNewOrUp return false, nil } le := s.leafVariants.GetHighestPrecedence(false, false, false) - if le == nil || onlyNewOrUpdated && !(le.IsNew || le.IsUpdated) { + if le == nil || onlyNewOrUpdated && (!le.IsNew && !le.IsUpdated) { return false, nil } } @@ -275,10 +275,12 @@ func xmlAddKeyElements(s Entry, parent *etree.Element) { // from the parent we get the keys as slice schemaKeys := parentSchema.GetSchemaKeys() + //issue #364: sort the slice sort.Strings(schemaKeys) - var treeElem Entry = s + treeElem := s + // the keys do match the levels up in the tree in reverse order // hence we init i with levelUp and count down for i := levelsUp - 1; i >= 0; i-- { diff --git a/pkg/utils/converter.go b/pkg/utils/converter.go index 8586e586..e4d94eac 100644 --- a/pkg/utils/converter.go +++ b/pkg/utils/converter.go @@ -248,9 +248,8 @@ func (c *Converter) ExpandContainerValue(ctx context.Context, p *sdcpb.Path, jv } // in case of json_ietf we need to cut the module prefix if k.Type.Type == "identityref" { - val := v found := false - _, val, found = strings.Cut(fmt.Sprintf("%v", v), ":") + _, val, found := strings.Cut(fmt.Sprintf("%v", v), ":") if found { v = val } diff --git a/pkg/utils/notification.go b/pkg/utils/notification.go index c9fd3688..e9370d26 100644 --- a/pkg/utils/notification.go +++ b/pkg/utils/notification.go @@ -136,7 +136,7 @@ func FromGNMITypedValue(ctx context.Context, v *gnmi.TypedValue) *sdcpb.TypedVal } case *gnmi.TypedValue_FloatVal: return &sdcpb.TypedValue{ - Value: &sdcpb.TypedValue_DoubleVal{DoubleVal: float64(v.GetFloatVal())}, + Value: &sdcpb.TypedValue_DoubleVal{DoubleVal: float64(v.GetFloatVal())}, //nolint:staticcheck } case *gnmi.TypedValue_DoubleVal: return &sdcpb.TypedValue{