mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2024-12-14 11:57:51 +00:00
nfd-master: implement --instance flag
This can be used to help running multiple parallel NFD deployments in the same cluster. The flag changes the node annotation namespace to <instance>.nfd.node.kubernetes.io allowing different nfd-master intances to store metadata in separate annotations.
This commit is contained in:
parent
705687192d
commit
e52ec3480f
6 changed files with 119 additions and 62 deletions
|
@ -66,7 +66,7 @@ func argsParse(argv []string) (master.Args, error) {
|
|||
%s [--prune] [--no-publish] [--label-whitelist=<pattern>] [--port=<port>]
|
||||
[--ca-file=<path>] [--cert-file=<path>] [--key-file=<path>]
|
||||
[--verify-node-name] [--extra-label-ns=<list>] [--resource-labels=<list>]
|
||||
[--kubeconfig=<path>]
|
||||
[--kubeconfig=<path>] [--instance=<name>]
|
||||
%s -h | --help
|
||||
%s --version
|
||||
|
||||
|
@ -75,6 +75,9 @@ func argsParse(argv []string) (master.Args, error) {
|
|||
--version Output version and exit.
|
||||
--prune Prune all NFD related attributes from all nodes
|
||||
of the cluster and exit.
|
||||
--instance=<name> Instance name. Used to separate annotation
|
||||
namespaces for multiple parallel deployments.
|
||||
[Default: ]
|
||||
--kubeconfig=<path> Kubeconfig to use [Default: ]
|
||||
of the cluster and exit.
|
||||
--port=<port> Port on which to listen for connections.
|
||||
|
@ -109,6 +112,12 @@ func argsParse(argv []string) (master.Args, error) {
|
|||
|
||||
// Parse argument values as usable types.
|
||||
var err error
|
||||
args.Instance = arguments["--instance"].(string)
|
||||
if ok, _ := regexp.MatchString(`^([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$`, args.Instance); args.Instance != "" && !ok {
|
||||
return args, fmt.Errorf("invalid --instance %q: instance name "+
|
||||
"must start and end with an alphanumeric character and may only contain "+
|
||||
"alphanumerics, `-`, `_` or `.`", args.Instance)
|
||||
}
|
||||
args.CaFile = arguments["--ca-file"].(string)
|
||||
args.CertFile = arguments["--cert-file"].(string)
|
||||
args.KeyFile = arguments["--key-file"].(string)
|
||||
|
|
|
@ -48,6 +48,22 @@ Example:
|
|||
nfd-master --port=443
|
||||
```
|
||||
|
||||
### --instance
|
||||
|
||||
The `--instance` flag makes it possible to run multiple NFD deployments in
|
||||
parallel. In practice, it separates the node annotations between deployments so
|
||||
that each of them can store metadata independently. The instance name must
|
||||
start and end with an alphanumeric character and may only contain alphanumeric
|
||||
characters, `-`, `_` or `.`.
|
||||
|
||||
Default: *empty*
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
nfd-master --instance=network
|
||||
```
|
||||
|
||||
### --ca-file
|
||||
|
||||
The `--ca-file` is one of the three flags (together with `--cert-file` and
|
||||
|
|
|
@ -80,12 +80,16 @@ An overview of the default feature labels:
|
|||
|
||||
NFD also annotates nodes it is running on:
|
||||
|
||||
| Annotation | Description
|
||||
| ----------------------------------------- | -----------
|
||||
| nfd.node.kubernetes.io/master.version | Version of the nfd-master instance running on the node. Informative use only.
|
||||
| nfd.node.kubernetes.io/worker.version | Version of the nfd-worker instance running on the node. Informative use only.
|
||||
| nfd.node.kubernetes.io/feature-labels | Comma-separated list of node labels managed by NFD. NFD uses this internally so must not be edited by users.
|
||||
| nfd.node.kubernetes.io/extended-resources | Comma-separated list of node extended resources managed by NFD. NFD uses this internally so must not be edited by users.
|
||||
| Annotation | Description
|
||||
| ------------------------------------------------------------ | -----------
|
||||
| [<instance>.]nfd.node.kubernetes.io/master.version | Version of the nfd-master instance running on the node. Informative use only.
|
||||
| [<instance>.]nfd.node.kubernetes.io/worker.version | Version of the nfd-worker instance running on the node. Informative use only.
|
||||
| [<instance>.]nfd.node.kubernetes.io/feature-labels | Comma-separated list of node labels managed by NFD. NFD uses this internally so must not be edited by users.
|
||||
| [<instance>.]nfd.node.kubernetes.io/extended-resources | Comma-separated list of node extended resources managed by NFD. NFD uses this internally so must not be edited by users.
|
||||
|
||||
NOTE: the [`--instance`](../advanced/master-commandline-reference.md#instance)
|
||||
command line flag affects the annotation names
|
||||
|
||||
Unapplicable annotations are not created, i.e. for example master.version is only created on nodes running nfd-master.
|
||||
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package nfdmaster
|
||||
|
||||
import (
|
||||
"path"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
@ -52,9 +53,10 @@ func newMockNode() *api.Node {
|
|||
|
||||
func newMockMaster(apihelper apihelper.APIHelpers) *nfdMaster {
|
||||
return &nfdMaster{
|
||||
nodeName: mockNodeName,
|
||||
args: Args{LabelWhiteList: regexp.MustCompile("")},
|
||||
apihelper: apihelper,
|
||||
nodeName: mockNodeName,
|
||||
annotationNs: AnnotationNsBase,
|
||||
args: Args{LabelWhiteList: regexp.MustCompile("")},
|
||||
apihelper: apihelper,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,13 +84,13 @@ func TestUpdateNodeFeatures(t *testing.T) {
|
|||
// Mock node with old features
|
||||
mockNode := newMockNode()
|
||||
mockNode.Labels[LabelNs+"/old-feature"] = "old-value"
|
||||
mockNode.Annotations[AnnotationNs+"/feature-labels"] = "old-feature"
|
||||
mockNode.Annotations[AnnotationNsBase+"/feature-labels"] = "old-feature"
|
||||
|
||||
Convey("When I successfully update the node with feature labels", func() {
|
||||
// Create a list of expected node metadata patches
|
||||
metadataPatches := []apihelper.JsonPatch{
|
||||
apihelper.NewJsonPatch("replace", "/metadata/annotations", AnnotationNs+"/feature-labels", strings.Join(fakeFeatureLabelNames, ",")),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", AnnotationNs+"/extended-resources", strings.Join(fakeExtResourceNames, ",")),
|
||||
apihelper.NewJsonPatch("replace", "/metadata/annotations", AnnotationNsBase+"/feature-labels", strings.Join(fakeFeatureLabelNames, ",")),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", AnnotationNsBase+"/extended-resources", strings.Join(fakeExtResourceNames, ",")),
|
||||
apihelper.NewJsonPatch("remove", "/metadata/labels", LabelNs+"/old-feature", ""),
|
||||
}
|
||||
for k, v := range fakeFeatureLabels {
|
||||
|
@ -169,7 +171,7 @@ func TestUpdateMasterNode(t *testing.T) {
|
|||
mockNode := newMockNode()
|
||||
Convey("When update operation succeeds", func() {
|
||||
expectedPatches := []apihelper.JsonPatch{
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", AnnotationNs+"/master.version", version.Get())}
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", AnnotationNsBase+"/master.version", version.Get())}
|
||||
mockHelper.On("GetClient").Return(mockClient, nil)
|
||||
mockHelper.On("GetNode", mockClient, mockNodeName).Return(mockNode, nil)
|
||||
mockHelper.On("PatchNode", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedPatches))).Return(nil)
|
||||
|
@ -211,10 +213,11 @@ func TestUpdateMasterNode(t *testing.T) {
|
|||
|
||||
func TestAddingExtResources(t *testing.T) {
|
||||
Convey("When adding extended resources", t, func() {
|
||||
mockMaster := newMockMaster(nil)
|
||||
Convey("When there are no matching labels", func() {
|
||||
mockNode := newMockNode()
|
||||
mockResourceLabels := ExtendedResources{}
|
||||
patches := createExtendedResourcePatches(mockNode, mockResourceLabels)
|
||||
patches := mockMaster.createExtendedResourcePatches(mockNode, mockResourceLabels)
|
||||
So(len(patches), ShouldEqual, 0)
|
||||
})
|
||||
|
||||
|
@ -225,7 +228,7 @@ func TestAddingExtResources(t *testing.T) {
|
|||
apihelper.NewJsonPatch("add", "/status/capacity", "feature-1", "1"),
|
||||
apihelper.NewJsonPatch("add", "/status/capacity", "feature-2", "2"),
|
||||
}
|
||||
patches := createExtendedResourcePatches(mockNode, mockResourceLabels)
|
||||
patches := mockMaster.createExtendedResourcePatches(mockNode, mockResourceLabels)
|
||||
So(sortJsonPatches(patches), ShouldResemble, sortJsonPatches(expectedPatches))
|
||||
})
|
||||
|
||||
|
@ -233,7 +236,7 @@ func TestAddingExtResources(t *testing.T) {
|
|||
mockNode := newMockNode()
|
||||
mockNode.Status.Capacity[api.ResourceName(LabelNs+"/feature-1")] = *resource.NewQuantity(1, resource.BinarySI)
|
||||
mockResourceLabels := ExtendedResources{LabelNs + "/feature-1": "1"}
|
||||
patches := createExtendedResourcePatches(mockNode, mockResourceLabels)
|
||||
patches := mockMaster.createExtendedResourcePatches(mockNode, mockResourceLabels)
|
||||
So(len(patches), ShouldEqual, 0)
|
||||
})
|
||||
|
||||
|
@ -245,7 +248,7 @@ func TestAddingExtResources(t *testing.T) {
|
|||
apihelper.NewJsonPatch("replace", "/status/capacity", "feature-1", "1"),
|
||||
apihelper.NewJsonPatch("replace", "/status/allocatable", "feature-1", "1"),
|
||||
}
|
||||
patches := createExtendedResourcePatches(mockNode, mockResourceLabels)
|
||||
patches := mockMaster.createExtendedResourcePatches(mockNode, mockResourceLabels)
|
||||
So(sortJsonPatches(patches), ShouldResemble, sortJsonPatches(expectedPatches))
|
||||
})
|
||||
})
|
||||
|
@ -253,22 +256,23 @@ func TestAddingExtResources(t *testing.T) {
|
|||
|
||||
func TestRemovingExtResources(t *testing.T) {
|
||||
Convey("When removing extended resources", t, func() {
|
||||
mockMaster := newMockMaster(nil)
|
||||
Convey("When none are removed", func() {
|
||||
mockNode := newMockNode()
|
||||
mockResourceLabels := ExtendedResources{LabelNs + "/feature-1": "1", LabelNs + "/feature-2": "2"}
|
||||
mockNode.Annotations[AnnotationNs+"/extended-resources"] = "feature-1,feature-2"
|
||||
mockNode.Annotations[AnnotationNsBase+"/extended-resources"] = "feature-1,feature-2"
|
||||
mockNode.Status.Capacity[api.ResourceName(LabelNs+"/feature-1")] = *resource.NewQuantity(1, resource.BinarySI)
|
||||
mockNode.Status.Capacity[api.ResourceName(LabelNs+"/feature-2")] = *resource.NewQuantity(2, resource.BinarySI)
|
||||
patches := createExtendedResourcePatches(mockNode, mockResourceLabels)
|
||||
patches := mockMaster.createExtendedResourcePatches(mockNode, mockResourceLabels)
|
||||
So(len(patches), ShouldEqual, 0)
|
||||
})
|
||||
Convey("When the related label is gone", func() {
|
||||
mockNode := newMockNode()
|
||||
mockResourceLabels := ExtendedResources{LabelNs + "/feature-4": "", LabelNs + "/feature-2": "2"}
|
||||
mockNode.Annotations[AnnotationNs+"/extended-resources"] = "feature-4,feature-2"
|
||||
mockNode.Annotations[AnnotationNsBase+"/extended-resources"] = "feature-4,feature-2"
|
||||
mockNode.Status.Capacity[api.ResourceName(LabelNs+"/feature-4")] = *resource.NewQuantity(4, resource.BinarySI)
|
||||
mockNode.Status.Capacity[api.ResourceName(LabelNs+"/feature-2")] = *resource.NewQuantity(2, resource.BinarySI)
|
||||
patches := createExtendedResourcePatches(mockNode, mockResourceLabels)
|
||||
patches := mockMaster.createExtendedResourcePatches(mockNode, mockResourceLabels)
|
||||
So(len(patches), ShouldBeGreaterThan, 0)
|
||||
})
|
||||
Convey("When the extended resource is no longer wanted", func() {
|
||||
|
@ -276,8 +280,8 @@ func TestRemovingExtResources(t *testing.T) {
|
|||
mockNode.Status.Capacity[api.ResourceName(LabelNs+"/feature-1")] = *resource.NewQuantity(1, resource.BinarySI)
|
||||
mockNode.Status.Capacity[api.ResourceName(LabelNs+"/feature-2")] = *resource.NewQuantity(2, resource.BinarySI)
|
||||
mockResourceLabels := ExtendedResources{LabelNs + "/feature-2": "2"}
|
||||
mockNode.Annotations[AnnotationNs+"/extended-resources"] = "feature-1,feature-2"
|
||||
patches := createExtendedResourcePatches(mockNode, mockResourceLabels)
|
||||
mockNode.Annotations[AnnotationNsBase+"/extended-resources"] = "feature-1,feature-2"
|
||||
patches := mockMaster.createExtendedResourcePatches(mockNode, mockResourceLabels)
|
||||
So(len(patches), ShouldBeGreaterThan, 0)
|
||||
})
|
||||
})
|
||||
|
@ -304,11 +308,14 @@ func TestSetLabels(t *testing.T) {
|
|||
|
||||
expectedStatusPatches := []apihelper.JsonPatch{}
|
||||
|
||||
wvAnnotation := path.Join(AnnotationNsBase, workerVersionAnnotation)
|
||||
flAnnotation := path.Join(AnnotationNsBase, featureLabelAnnotation)
|
||||
erAnnotation := path.Join(AnnotationNsBase, extendedResourceAnnotation)
|
||||
Convey("When node update succeeds", func() {
|
||||
expectedPatches := []apihelper.JsonPatch{
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", workerVersionAnnotation, workerVer),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", featureLabelAnnotation, strings.Join(mockLabelNames, ",")),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", extendedResourceAnnotation, ""),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", wvAnnotation, workerVer),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", flAnnotation, strings.Join(mockLabelNames, ",")),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", erAnnotation, ""),
|
||||
}
|
||||
for k, v := range mockLabels {
|
||||
expectedPatches = append(expectedPatches, apihelper.NewJsonPatch("add", "/metadata/labels", LabelNs+"/"+k, v))
|
||||
|
@ -326,9 +333,9 @@ func TestSetLabels(t *testing.T) {
|
|||
|
||||
Convey("When --label-whitelist is specified", func() {
|
||||
expectedPatches := []apihelper.JsonPatch{
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", workerVersionAnnotation, workerVer),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", featureLabelAnnotation, "feature-2"),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", extendedResourceAnnotation, ""),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", wvAnnotation, workerVer),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", flAnnotation, "feature-2"),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", erAnnotation, ""),
|
||||
apihelper.NewJsonPatch("add", "/metadata/labels", LabelNs+"/feature-2", mockLabels["feature-2"]),
|
||||
}
|
||||
|
||||
|
@ -343,20 +350,22 @@ func TestSetLabels(t *testing.T) {
|
|||
})
|
||||
})
|
||||
|
||||
Convey("When --extra-label-ns is specified", func() {
|
||||
Convey("When --extra-label-ns and --instance are specified", func() {
|
||||
// In the gRPC request the label names may omit the default ns
|
||||
instance := "foo"
|
||||
mockLabels := map[string]string{"feature-1": "val-1",
|
||||
"valid.ns/feature-2": "val-2",
|
||||
"invalid.ns/feature-3": "val-3"}
|
||||
expectedPatches := []apihelper.JsonPatch{
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", workerVersionAnnotation, workerVer),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", featureLabelAnnotation, "feature-1,valid.ns/feature-2"),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", extendedResourceAnnotation, ""),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", instance+"."+wvAnnotation, workerVer),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", instance+"."+flAnnotation, "feature-1,valid.ns/feature-2"),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", instance+"."+erAnnotation, ""),
|
||||
apihelper.NewJsonPatch("add", "/metadata/labels", LabelNs+"/feature-1", mockLabels["feature-1"]),
|
||||
apihelper.NewJsonPatch("add", "/metadata/labels", "valid.ns/feature-2", mockLabels["valid.ns/feature-2"]),
|
||||
}
|
||||
|
||||
mockMaster.args.ExtraLabelNs = map[string]struct{}{"valid.ns": struct{}{}}
|
||||
mockMaster.annotationNs = instance + "." + AnnotationNsBase
|
||||
mockHelper.On("GetClient").Return(mockClient, nil)
|
||||
mockHelper.On("GetNode", mockClient, workerName).Return(mockNode, nil)
|
||||
mockHelper.On("PatchNode", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedPatches))).Return(nil)
|
||||
|
@ -366,14 +375,14 @@ func TestSetLabels(t *testing.T) {
|
|||
Convey("Error is nil", func() {
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
mockMaster.annotationNs = AnnotationNsBase
|
||||
})
|
||||
|
||||
Convey("When --resource-labels is specified", func() {
|
||||
expectedPatches := []apihelper.JsonPatch{
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", workerVersionAnnotation, workerVer),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", featureLabelAnnotation, "feature-2"),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", extendedResourceAnnotation, "feature-1,feature-3"),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", wvAnnotation, workerVer),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", flAnnotation, "feature-2"),
|
||||
apihelper.NewJsonPatch("add", "/metadata/annotations", erAnnotation, "feature-1,feature-3"),
|
||||
apihelper.NewJsonPatch("add", "/metadata/labels", LabelNs+"/feature-2", mockLabels["feature-2"]),
|
||||
}
|
||||
expectedStatusPatches := []apihelper.JsonPatch{
|
||||
|
|
|
@ -45,14 +45,14 @@ const (
|
|||
// Namespace for feature labels
|
||||
LabelNs = "feature.node.kubernetes.io"
|
||||
|
||||
// Namespace for all NFD-related annotations
|
||||
AnnotationNs = "nfd.node.kubernetes.io"
|
||||
// Base namespace for all NFD-related annotations
|
||||
AnnotationNsBase = "nfd.node.kubernetes.io"
|
||||
|
||||
// NFD Annotations
|
||||
extendedResourceAnnotation = AnnotationNs + "/extended-resources"
|
||||
featureLabelAnnotation = AnnotationNs + "/feature-labels"
|
||||
masterVersionAnnotation = AnnotationNs + "/master.version"
|
||||
workerVersionAnnotation = AnnotationNs + "/worker.version"
|
||||
extendedResourceAnnotation = "extended-resources"
|
||||
featureLabelAnnotation = "feature-labels"
|
||||
masterVersionAnnotation = "master.version"
|
||||
workerVersionAnnotation = "worker.version"
|
||||
)
|
||||
|
||||
// package loggers
|
||||
|
@ -75,6 +75,7 @@ type Args struct {
|
|||
CaFile string
|
||||
CertFile string
|
||||
ExtraLabelNs map[string]struct{}
|
||||
Instance string
|
||||
KeyFile string
|
||||
Kubeconfig string
|
||||
LabelWhiteList *regexp.Regexp
|
||||
|
@ -92,18 +93,26 @@ type NfdMaster interface {
|
|||
}
|
||||
|
||||
type nfdMaster struct {
|
||||
args Args
|
||||
nodeName string
|
||||
server *grpc.Server
|
||||
ready chan bool
|
||||
apihelper apihelper.APIHelpers
|
||||
args Args
|
||||
nodeName string
|
||||
annotationNs string
|
||||
server *grpc.Server
|
||||
ready chan bool
|
||||
apihelper apihelper.APIHelpers
|
||||
}
|
||||
|
||||
// Create new NfdMaster server instance.
|
||||
func NewNfdMaster(args Args) (NfdMaster, error) {
|
||||
nfd := &nfdMaster{args: args,
|
||||
nodeName: os.Getenv("NODE_NAME"),
|
||||
ready: make(chan bool, 1)}
|
||||
ready: make(chan bool, 1),
|
||||
}
|
||||
|
||||
if args.Instance == "" {
|
||||
nfd.annotationNs = AnnotationNsBase
|
||||
} else {
|
||||
nfd.annotationNs = args.Instance + "." + AnnotationNsBase
|
||||
}
|
||||
|
||||
// Check TLS related args
|
||||
if args.CertFile != "" || args.KeyFile != "" || args.CaFile != "" {
|
||||
|
@ -128,6 +137,9 @@ func NewNfdMaster(args Args) (NfdMaster, error) {
|
|||
// is called.
|
||||
func (m *nfdMaster) Run() error {
|
||||
stdoutLogger.Printf("Node Feature Discovery Master %s", version.Get())
|
||||
if m.args.Instance != "" {
|
||||
stdoutLogger.Printf("Master instance: '%s'", m.args.Instance)
|
||||
}
|
||||
stdoutLogger.Printf("NodeName: '%s'", m.nodeName)
|
||||
|
||||
if m.args.Prune {
|
||||
|
@ -229,7 +241,7 @@ func (m *nfdMaster) prune() error {
|
|||
return err
|
||||
}
|
||||
for a := range node.Annotations {
|
||||
if strings.HasPrefix(a, AnnotationNs) {
|
||||
if strings.HasPrefix(a, m.annotationNs) {
|
||||
delete(node.Annotations, a)
|
||||
}
|
||||
}
|
||||
|
@ -254,7 +266,10 @@ func (m *nfdMaster) updateMasterNode() error {
|
|||
}
|
||||
|
||||
// Advertise NFD version as an annotation
|
||||
p := createPatches(nil, node.Annotations, Annotations{masterVersionAnnotation: version.Get()}, "/metadata/annotations")
|
||||
p := createPatches(nil,
|
||||
node.Annotations,
|
||||
Annotations{m.annotationName(masterVersionAnnotation): version.Get()},
|
||||
"/metadata/annotations")
|
||||
err = m.apihelper.PatchNode(cli, node.Name, p)
|
||||
if err != nil {
|
||||
stderrLogger.Printf("failed to patch node annotations: %v", err)
|
||||
|
@ -343,7 +358,7 @@ func (m *nfdMaster) SetLabels(c context.Context, r *pb.SetLabelsRequest) (*pb.Se
|
|||
|
||||
if !m.args.NoPublish {
|
||||
// Advertise NFD worker version as an annotation
|
||||
annotations := Annotations{workerVersionAnnotation: r.NfdVersion}
|
||||
annotations := Annotations{m.annotationName(workerVersionAnnotation): r.NfdVersion}
|
||||
|
||||
err := m.updateNodeFeatures(r.NodeName, labels, annotations, extendedResources)
|
||||
if err != nil {
|
||||
|
@ -376,7 +391,7 @@ func (m *nfdMaster) updateNodeFeatures(nodeName string, labels Labels, annotatio
|
|||
labelKeys = append(labelKeys, strings.TrimPrefix(key, LabelNs+"/"))
|
||||
}
|
||||
sort.Strings(labelKeys)
|
||||
annotations[featureLabelAnnotation] = strings.Join(labelKeys, ",")
|
||||
annotations[m.annotationName(featureLabelAnnotation)] = strings.Join(labelKeys, ",")
|
||||
|
||||
// Store names of extended resources in an annotation
|
||||
extendedResourceKeys := make([]string, 0, len(extendedResources))
|
||||
|
@ -385,10 +400,10 @@ func (m *nfdMaster) updateNodeFeatures(nodeName string, labels Labels, annotatio
|
|||
extendedResourceKeys = append(extendedResourceKeys, strings.TrimPrefix(key, LabelNs+"/"))
|
||||
}
|
||||
sort.Strings(extendedResourceKeys)
|
||||
annotations[extendedResourceAnnotation] = strings.Join(extendedResourceKeys, ",")
|
||||
annotations[m.annotationName(extendedResourceAnnotation)] = strings.Join(extendedResourceKeys, ",")
|
||||
|
||||
// Create JSON patches for changes in labels and annotations
|
||||
oldLabels := stringToNsNames(node.Annotations[featureLabelAnnotation], LabelNs)
|
||||
oldLabels := stringToNsNames(node.Annotations[m.annotationName(featureLabelAnnotation)], LabelNs)
|
||||
patches := createPatches(oldLabels, node.Labels, labels, "/metadata/labels")
|
||||
patches = append(patches, createPatches(nil, node.Annotations, annotations, "/metadata/annotations")...)
|
||||
|
||||
|
@ -404,7 +419,7 @@ func (m *nfdMaster) updateNodeFeatures(nodeName string, labels Labels, annotatio
|
|||
}
|
||||
|
||||
// patch node status with extended resource changes
|
||||
patches = createExtendedResourcePatches(node, extendedResources)
|
||||
patches = m.createExtendedResourcePatches(node, extendedResources)
|
||||
err = m.apihelper.PatchNodeStatus(cli, node.Name, patches)
|
||||
if err != nil {
|
||||
stderrLogger.Printf("error while patching extended resources: %s", err.Error())
|
||||
|
@ -414,6 +429,10 @@ func (m *nfdMaster) updateNodeFeatures(nodeName string, labels Labels, annotatio
|
|||
return err
|
||||
}
|
||||
|
||||
func (m *nfdMaster) annotationName(name string) string {
|
||||
return path.Join(m.annotationNs, name)
|
||||
}
|
||||
|
||||
// Remove any labels having the given prefix
|
||||
func removeLabelsWithPrefix(n *api.Node, search string) []apihelper.JsonPatch {
|
||||
var p []apihelper.JsonPatch
|
||||
|
@ -456,11 +475,11 @@ func createPatches(removeKeys []string, oldItems map[string]string, newItems map
|
|||
|
||||
// createExtendedResourcePatches returns a slice of operations to perform on
|
||||
// the node status
|
||||
func createExtendedResourcePatches(n *api.Node, extendedResources ExtendedResources) []apihelper.JsonPatch {
|
||||
func (m *nfdMaster) createExtendedResourcePatches(n *api.Node, extendedResources ExtendedResources) []apihelper.JsonPatch {
|
||||
patches := []apihelper.JsonPatch{}
|
||||
|
||||
// Form a list of namespaced resource names managed by us
|
||||
oldResources := stringToNsNames(n.Annotations[extendedResourceAnnotation], LabelNs)
|
||||
oldResources := stringToNsNames(n.Annotations[m.annotationName(extendedResourceAnnotation)], LabelNs)
|
||||
|
||||
// figure out which resources to remove
|
||||
for _, resource := range oldResources {
|
||||
|
|
|
@ -393,7 +393,7 @@ func cleanupNode(cs clientset.Interface) {
|
|||
|
||||
// Remove annotations
|
||||
for key := range node.Annotations {
|
||||
if strings.HasPrefix(key, master.AnnotationNs) {
|
||||
if strings.HasPrefix(key, master.AnnotationNsBase) {
|
||||
delete(node.Annotations, key)
|
||||
update = true
|
||||
}
|
||||
|
@ -573,7 +573,7 @@ var _ = framework.KubeDescribe("[NFD] Node Feature Discovery", func() {
|
|||
gomega.Expect(node.Annotations).To(gomega.HaveKey(k))
|
||||
}
|
||||
for k := range node.Annotations {
|
||||
if strings.HasPrefix(k, master.AnnotationNs) {
|
||||
if strings.HasPrefix(k, master.AnnotationNsBase) {
|
||||
if _, ok := nodeConf.ExpectedAnnotationValues[k]; ok {
|
||||
continue
|
||||
}
|
||||
|
@ -587,7 +587,7 @@ var _ = framework.KubeDescribe("[NFD] Node Feature Discovery", func() {
|
|||
|
||||
// Node running nfd-master should have master version annotation
|
||||
if node.Name == masterPod.Spec.NodeName {
|
||||
gomega.Expect(node.Annotations).To(gomega.HaveKey(master.AnnotationNs + "master.version"))
|
||||
gomega.Expect(node.Annotations).To(gomega.HaveKey(master.AnnotationNsBase + "master.version"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue