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

poc #2

Closed
wants to merge 1 commit into from
Closed
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
13 changes: 12 additions & 1 deletion cmd/nic-feature-discovery/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package app
import (
"context"
"fmt"
"path/filepath"

"github.com/go-logr/logr"
"github.com/spf13/cobra"
Expand All @@ -30,8 +31,14 @@ import (
_ "k8s.io/component-base/logs/json/register"

"github.com/Mellanox/nic-feature-discovery/cmd/nic-feature-discovery/app/options"
"github.com/Mellanox/nic-feature-discovery/pkg/daemon"
"github.com/Mellanox/nic-feature-discovery/pkg/feature"
"github.com/Mellanox/nic-feature-discovery/pkg/utils/signals"
"github.com/Mellanox/nic-feature-discovery/pkg/utils/version"
"github.com/Mellanox/nic-feature-discovery/pkg/writer"

// import feature sources
_ "github.com/Mellanox/nic-feature-discovery/pkg/feature/sources"
)

// NewNICFeatureDiscoveryCommand creates a new command
Expand Down Expand Up @@ -81,7 +88,11 @@ func NewNICFeatureDiscoveryCommand() *cobra.Command {
func RunNICFeatureDiscovery(ctx context.Context, opts *options.Options) error {
logger := logr.FromContextOrDiscard(ctx)
logger.Info("start NIC feature discovery", "Options", opts)
<-ctx.Done()

labelWriter := writer.NewLabelWriter(filepath.Join(opts.NFDFeaturesPath, opts.FeatureFileName),
logger.WithName("label-writer"))
d := daemon.New(opts.FeatureScanInterval, labelWriter, feature.Sources)
d.Run(ctx)

return nil
}
15 changes: 12 additions & 3 deletions cmd/nic-feature-discovery/app/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,17 @@ import (
"github.com/Mellanox/nic-feature-discovery/pkg/utils/filesystem"
)

const (
defaultNFDFeaturePath = "/etc/node-feature-discovery/features.d/"
defaultFeatureFileName = "nvidia-com-nic-feature-discovery.features"
)

// New creates new Options
func New() *Options {
return &Options{
NFDFeaturesPath: "/etc/node-feature-discovery/features.d/",
FeatureFileName: "nvidia-com-nic-feature-discovery.features",
FeatureScanInterval: 5 * time.Minute,
NFDFeaturesPath: defaultNFDFeaturePath,
FeatureFileName: defaultFeatureFileName,
FeatureScanInterval: 1 * time.Minute,
LogConfig: logsapi.NewLoggingConfiguration(),
}
}
Expand Down Expand Up @@ -66,6 +71,10 @@ func (o *Options) AddNamedFlagSets(sharedFS *cliflag.NamedFlagSets) {
func (o *Options) Validate() error {
var err error

if err = logsapi.ValidateAndApply(o.LogConfig, nil); err != nil {
return fmt.Errorf("failed to validate logging flags. %w", err)
}

if err = filesystem.FolderExist(o.NFDFeaturesPath); err != nil {
return fmt.Errorf("failed to validate NFD features path. %w", err)
}
Expand Down
50 changes: 50 additions & 0 deletions deployment/k8s/daemonset.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nic-feature-discovery-ds
namespace: kube-system
labels:
tier: node
app: nic-feature-discovery
name: nic-feature-discovery
spec:
selector:
matchLabels:
name: nic-feature-discovery
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
tier: node
app: nic-feature-discovery
name: nic-feature-discovery
spec:
tolerations:
- operator: Exists
effect: NoSchedule
containers:
- name: nic-feature-discovery
image: ghcr.io/mellanox/nic-feature-discovery:latest
command: [ "/nic-feature-discovery" ]
args:
- --v=0
- --logging-format=json
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "300m"
memory: "300Mi"
securityContext:
privileged: true
volumeMounts:
- name: features-dir
mountPath: /etc/node-feature-discovery/features.d
terminationGracePeriodSeconds: 10
volumes:
- name: features-dir
hostPath:
path: /etc/node-feature-discovery/features.d
type: DirectoryOrCreate
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.20

require (
github.com/go-logr/logr v1.2.4
github.com/google/renameio/v2 v2.0.0
github.com/spf13/cobra v1.7.0
k8s.io/component-base v0.27.4
k8s.io/klog/v2 v2.100.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
Expand Down
76 changes: 76 additions & 0 deletions pkg/daemon/daemon.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package daemon

import (
"context"
"time"

"github.com/go-logr/logr"

"github.com/Mellanox/nic-feature-discovery/pkg/feature"
"github.com/Mellanox/nic-feature-discovery/pkg/label"
"github.com/Mellanox/nic-feature-discovery/pkg/writer"
)

// New creates a new Daemon
func New(scanInterval time.Duration, labelWriter writer.LabelWriter, sources []feature.Source) *Daemon {
return &Daemon{
scanInterval: scanInterval,
writer: labelWriter,
sources: sources,
}
}

// Daemon periodically scans for features and writes labels
type Daemon struct {
scanInterval time.Duration
writer writer.LabelWriter
sources []feature.Source
}

// Run daemon control loop
func (d *Daemon) Run(ctx context.Context) {
log := logr.FromContextOrDiscard(ctx)
d.discover(ctx)
OUTER:
for {
select {
case <-ctx.Done():
log.Info("context closed exiting daemon")

break OUTER
case <-time.After(d.scanInterval):
d.discover(ctx)
}
}
}

func (d *Daemon) discover(ctx context.Context) {
log := logr.FromContextOrDiscard(ctx)
log.WithName("discovery-daemon")

log.Info("discovering features")

features := make([]feature.Feature, 0)
for _, s := range d.sources {
log.V(2).Info("discovering features from source", "name", s.Name())
sourceFeatures, err := s.Discover(ctx)
if err != nil {
log.Error(err, "failed to discover features from source", "name", s.Name())

continue
}
features = append(features, sourceFeatures...)
}

labels := make([]label.Label, 0)
for _, f := range features {
labels = append(labels, f.Labels()...)
}

log.Info("conditionally updating features file")
err := d.writer.Write(labels)
if err != nil {
log.Error(err, "failed to write feature labels")
}
log.Info("discovery complete")
}
46 changes: 46 additions & 0 deletions pkg/feature/feature.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
Copyright 2023, NVIDIA CORPORATION & AFFILIATES
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

SPDX-License-Identifier: Apache-2.0
SPDX-FileCopyrightText: Copyright 2023, NVIDIA CORPORATION & AFFILIATES
*/

package feature

import (
"context"

"github.com/Mellanox/nic-feature-discovery/pkg/label"
)

var Sources []Source

// Feature exposes a set of key,value lables
type Feature interface {
// Name of Feature
Name() string
// Labels returns the list of Labels for Feature
Labels() []label.Label
}

// Source is a souce of features
type Source interface {
// Name of Source
Name() string
// Discover discovers Features
Discover(ctx context.Context) ([]Feature, error)
}

// AddToSources registers Sources
func AddToSources(s Source) {
Sources = append(Sources, s)
}
51 changes: 51 additions & 0 deletions pkg/feature/internal/common/generic_feature.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
Copyright 2023, NVIDIA CORPORATION & AFFILIATES
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

SPDX-License-Identifier: Apache-2.0
SPDX-FileCopyrightText: Copyright 2023, NVIDIA CORPORATION & AFFILIATES
*/

package common

import (
"github.com/Mellanox/nic-feature-discovery/pkg/label"
)

// NewGenericFeature creates a new GenericFeature
func NewGenericFeature(name string) *GenericFeature {
return &GenericFeature{
name: name,
}
}

// GenericFeature is a generic implementation of Feature
type GenericFeature struct {
name string
labels []label.Label
}

// Name of Feature
func (gf *GenericFeature) Name() string {
return gf.name
}

// Labels returns the list of Labels for Feature
func (gf *GenericFeature) Labels() []label.Label {
return gf.labels
}

// AddLabel adds a key=value label to GenericFeature
func (gf *GenericFeature) AddLabel(k, v string) *GenericFeature {
gf.labels = append(gf.labels, label.Label{Key: k, Value: v})

return gf
}
31 changes: 31 additions & 0 deletions pkg/feature/internal/common/prefix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
Copyright 2023, NVIDIA CORPORATION & AFFILIATES
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

SPDX-License-Identifier: Apache-2.0
SPDX-FileCopyrightText: Copyright 2023, NVIDIA CORPORATION & AFFILIATES
*/

package common

const (
defaultPrefix = "nvidia.com"
)

// DefaultPrefixedKey creates a key with default prefix
func DefaultPrefixedKey(key string) string {
return PrefixedKey(defaultPrefix, key)
}

// PrefixedKey creates a prefixed key
func PrefixedKey(prefix, key string) string {
return prefix + "/" + key
}
Loading
Loading