Skip to content
Merged
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
- The NFD engine now rejects an empty generated object set when cleanup is enabled, preserving the last published topology instead of deleting every Topograph-managed NFD object after an empty provider result or over-narrow node selection.
- The NFD engine now groups nodes with `nvidia.com/gpu.clique` by that authoritative accelerator value instead of omitting their accelerator attribute.
- The NFD engine now publishes the `system.name/nodename` attribute required by NFD to populate `NodeFeatureGroup.status.nodes`, including for simulated KWOK nodes where no NFD worker executes.
- The DRA provider now matches nodes using the `topograph.nvidia.com/instance` annotation instead of assuming the instance ID equals the Kubernetes node name.
- `kwok-nodes` now maps generated instance IDs back to model hostnames when naming Kubernetes nodes and writing the Topograph instance annotation.
- The node-observer now discovers the optional node-data-broker through `NODE_DATA_BROKER_NAME` and `NODE_DATA_BROKER_NAMESPACE` and gates topology generation on the broker DaemonSet's desired and ready replica counts. Helm injects the variables only when `nodeDataBroker.enabled=true`, so disabling the broker cannot leave the observer waiting for nonexistent pods.
- The node-observer reports an actionable error and defers topology generation when an enabled node-data-broker DaemonSet has zero desired replicas.
Expand Down
13 changes: 10 additions & 3 deletions pkg/providers/dra/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/klog/v2"

"github.com/NVIDIA/topograph/internal/config"
"github.com/NVIDIA/topograph/internal/httperr"
Expand All @@ -30,7 +31,7 @@ const (

type Provider struct {
config *rest.Config
client *kubernetes.Clientset
client kubernetes.Interface
params *Params
}

Expand Down Expand Up @@ -109,8 +110,14 @@ func (p *Provider) GenerateTopologyConfig(ctx context.Context, _ *int, instances
}

i2n := instances[indx].Instances
if host, ok := i2n[node.Name]; ok {
domainMap.AddHost(clusterID, node.Name, host)
instanceID, ok := node.Annotations[topology.KeyNodeInstance]
if !ok || instanceID == "" {
Comment thread
dmitsh marked this conversation as resolved.
klog.Warningf("missing or empty %q annotation in node %s", topology.KeyNodeInstance, node.Name)
continue
}

if host, ok := i2n[instanceID]; ok {
domainMap.AddHost(clusterID, instanceID, host)
}
}

Expand Down
34 changes: 34 additions & 0 deletions pkg/providers/dra/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@
package dra

import (
"context"
"testing"

"github.com/NVIDIA/topograph/pkg/topology"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
)

func TestGetParameters(t *testing.T) {
Expand Down Expand Up @@ -53,3 +57,33 @@ func TestGetParameters(t *testing.T) {
})
}
}

func TestGenerateTopologyConfigUsesAnnotatedInstanceID(t *testing.T) {
node := &corev1.Node{ObjectMeta: metav1.ObjectMeta{
Name: "k8s-node-1",
Labels: map[string]string{
DomainLabel: "clique-1",
},
Annotations: map[string]string{
topology.KeyNodeInstance: "instance-123",
topology.KeyNodeRegion: "local",
},
}}
provider := &Provider{
client: fake.NewSimpleClientset(node),
params: &Params{},
}
instances := []topology.ComputeInstances{{
Region: "local",
Instances: map[string]string{
"instance-123": "scheduler-node-1",
},
}}

graph, httpErr := provider.GenerateTopologyConfig(context.Background(), nil, instances)

require.Nil(t, httpErr)
expectedDomains := topology.NewDomainMap()
expectedDomains.AddHost("clique-1", "instance-123", "scheduler-node-1")
require.Equal(t, expectedDomains, graph.Domains)
}
Loading