1
0
Fork 0
mirror of https://github.com/kubernetes-sigs/node-feature-discovery.git synced 2025-03-30 19:54:46 +00:00

topologyupdater: Updates based on latest changes made to CRD API

There have been recent changes made to the noderesourcetopology API
storing the proto file generated using go-to-protobuf tool and
this code inports the proto generated in the API in the topology-updater.proto
The PRs corresponding to the changes are as follows:
https://github.com/k8stopologyawareschedwg/noderesourcetopology-api/pull/9
https://github.com/k8stopologyawareschedwg/noderesourcetopology-api/pull/13

Commands used to generate topology-updater.pb.go file:

go install github.com/golang/protobuf/protoc-gen-go@v1.4.3
go mod vendor
protoc --go_opt=paths=source_relative  --go_out=plugins=grpc:. pkg/topologyupdater/topology-updater.proto -I. -Ivendor

As part of implmentation of this patch, reserved (non-allocatable) CPUs
are evaluated by performing a difference between all the CPUs on a system
(determined by using ghw) and allocatable CPUs (determined by querying
GetAllocatableResources podResource API endpoint).

When aggregator creates the NUMA zones, it will skip the zone creation if
there are no allocatable resources. In this update we creates those missing
zone with zero allocatable/available resources so we won't have holes in the
array of reported zones.

Co-Authored-by: Talor Itzhak <titzhak@redhat.com>
Signed-off-by: Swati Sehgal <swsehgal@redhat.com>
This commit is contained in:
Swati Sehgal 2021-07-13 23:24:58 +01:00
parent 832f82baaa
commit a311719d1e
10 changed files with 205 additions and 527 deletions

View file

@ -106,6 +106,7 @@ mock:
apigen: apigen:
protoc --go_opt=paths=source_relative --go_out=plugins=grpc:. pkg/labeler/labeler.proto protoc --go_opt=paths=source_relative --go_out=plugins=grpc:. pkg/labeler/labeler.proto
protoc --go_opt=paths=source_relative --go_out=plugins=grpc:. pkg/topologyupdater/topology-updater.proto
gofmt: gofmt:
@$(GO_FMT) -w -l $$(find . -name '*.go') @$(GO_FMT) -w -l $$(find . -name '*.go')

3
go.mod
View file

@ -8,7 +8,7 @@ require (
github.com/golang/protobuf v1.5.2 github.com/golang/protobuf v1.5.2
github.com/google/go-cmp v0.5.5 github.com/google/go-cmp v0.5.5
github.com/jaypipes/ghw v0.8.1-0.20210827132705-c7224150a17e github.com/jaypipes/ghw v0.8.1-0.20210827132705-c7224150a17e
github.com/k8stopologyawareschedwg/noderesourcetopology-api v0.0.9 github.com/k8stopologyawareschedwg/noderesourcetopology-api v0.0.10
github.com/klauspost/cpuid/v2 v2.0.9 github.com/klauspost/cpuid/v2 v2.0.9
github.com/onsi/ginkgo v1.14.0 github.com/onsi/ginkgo v1.14.0
github.com/onsi/gomega v1.10.1 github.com/onsi/gomega v1.10.1
@ -17,6 +17,7 @@ require (
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
github.com/vektra/errors v0.0.0-20140903201135-c64d83aba85a github.com/vektra/errors v0.0.0-20140903201135-c64d83aba85a
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
google.golang.org/grpc v1.38.0 google.golang.org/grpc v1.38.0
google.golang.org/protobuf v1.27.1 google.golang.org/protobuf v1.27.1
k8s.io/api v0.22.0 k8s.io/api v0.22.0

7
go.sum
View file

@ -416,8 +416,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/k8stopologyawareschedwg/noderesourcetopology-api v0.0.9 h1:kdyhXrB7d/1atUosPAAeRcAgtjfju6xlzt97PPgXv2o= github.com/k8stopologyawareschedwg/noderesourcetopology-api v0.0.10 h1:wHS+TOQfFY67wkS1roZ5WVyihnE/IQmVsD0zzKtzHrU=
github.com/k8stopologyawareschedwg/noderesourcetopology-api v0.0.9/go.mod h1:zRoCNg6LjSQewUwnpORw1VT9mP0rGNQlYy4WYaGWvHo= github.com/k8stopologyawareschedwg/noderesourcetopology-api v0.0.10/go.mod h1:yJo22okt35DQhvNw3Hgpaol6/oryET8Y5n1CJb9R5mM=
github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw= github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw=
github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
@ -891,8 +891,9 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=

View file

@ -178,7 +178,6 @@ func (w *nfdTopologyUpdater) Update(zones v1alpha1.ZoneList) error {
if err != nil { if err != nil {
return fmt.Errorf("failed to advertise node topology: %w", err) return fmt.Errorf("failed to advertise node topology: %w", err)
} }
return nil return nil
} }
@ -216,25 +215,16 @@ func (w *nfdTopologyUpdater) Disconnect() {
func advertiseNodeTopology(client pb.NodeTopologyClient, zoneInfo v1alpha1.ZoneList, tmPolicy string, nodeName string) error { func advertiseNodeTopology(client pb.NodeTopologyClient, zoneInfo v1alpha1.ZoneList, tmPolicy string, nodeName string) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel() defer cancel()
zones := make([]*pb.Zone, len(zoneInfo)) zones := make([]*v1alpha1.Zone, len(zoneInfo))
// TODO: Avoid copying of data to allow returning the zone info // TODO: Avoid copying of data to allow returning the zone info
// directly in a compatible data type (i.e. []*v1alpha1.Zone). // directly in a compatible data type (i.e. []*v1alpha1.Zone).
for i, zone := range zoneInfo { for i, zone := range zoneInfo {
resInfo := make([]*pb.ResourceInfo, len(zone.Resources)) zones[i] = &v1alpha1.Zone{
for j, info := range zone.Resources {
resInfo[j] = &pb.ResourceInfo{
Name: info.Name,
Allocatable: info.Allocatable.String(),
Capacity: info.Capacity.String(),
}
}
zones[i] = &pb.Zone{
Name: zone.Name, Name: zone.Name,
Type: zone.Type, Type: zone.Type,
Parent: zone.Parent, Parent: zone.Parent,
Resources: resInfo, Resources: zone.Resources,
Costs: updateMap(zone.Costs), Costs: zone.Costs,
} }
} }
@ -254,13 +244,3 @@ func advertiseNodeTopology(client pb.NodeTopologyClient, zoneInfo v1alpha1.ZoneL
return nil return nil
} }
func updateMap(data []v1alpha1.CostInfo) []*pb.CostInfo {
ret := make([]*pb.CostInfo, len(data))
for i, cost := range data {
ret[i] = &pb.CostInfo{
Name: cost.Name,
Value: int32(cost.Value),
}
}
return ret
}

View file

@ -24,7 +24,7 @@ import (
v1alpha1 "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/apis/topology/v1alpha1" v1alpha1 "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/apis/topology/v1alpha1"
. "github.com/smartystreets/goconvey/convey" . "github.com/smartystreets/goconvey/convey"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/api/resource"
nfdclient "sigs.k8s.io/node-feature-discovery/pkg/nfd-client" nfdclient "sigs.k8s.io/node-feature-discovery/pkg/nfd-client"
u "sigs.k8s.io/node-feature-discovery/pkg/nfd-client/topology-updater" u "sigs.k8s.io/node-feature-discovery/pkg/nfd-client/topology-updater"
nfdmaster "sigs.k8s.io/node-feature-discovery/pkg/nfd-master" nfdmaster "sigs.k8s.io/node-feature-discovery/pkg/nfd-master"
@ -93,8 +93,9 @@ func TestUpdate(t *testing.T) {
resourceInfo := v1alpha1.ResourceInfoList{ resourceInfo := v1alpha1.ResourceInfoList{
v1alpha1.ResourceInfo{ v1alpha1.ResourceInfo{
Name: "cpu", Name: "cpu",
Allocatable: intstr.FromString("2"), Available: resource.MustParse("2"),
Capacity: intstr.FromString("4"), Allocatable: resource.MustParse("4"),
Capacity: resource.MustParse("4"),
}, },
} }
zones := v1alpha1.ZoneList{ zones := v1alpha1.ZoneList{
@ -135,8 +136,9 @@ func TestRunTls(t *testing.T) {
resourceInfo := v1alpha1.ResourceInfoList{ resourceInfo := v1alpha1.ResourceInfoList{
v1alpha1.ResourceInfo{ v1alpha1.ResourceInfo{
Name: "cpu", Name: "cpu",
Allocatable: intstr.FromString("2"), Available: resource.MustParse("2"),
Capacity: intstr.FromString("4"), Allocatable: resource.MustParse("4"),
Capacity: resource.MustParse("4"),
}, },
} }
zones := v1alpha1.ZoneList{ zones := v1alpha1.ZoneList{

View file

@ -39,7 +39,6 @@ import (
api "k8s.io/api/core/v1" api "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"sigs.k8s.io/node-feature-discovery/pkg/apihelper" "sigs.k8s.io/node-feature-discovery/pkg/apihelper"
@ -450,7 +449,7 @@ func (m *nfdMaster) UpdateNodeTopology(c context.Context, r *topologypb.NodeTopo
if !m.args.NoPublish { if !m.args.NoPublish {
err := m.updateCR(r.NodeName, r.TopologyPolicies, r.Zones, m.args.NRTNamespace) err := m.updateCR(r.NodeName, r.TopologyPolicies, r.Zones, m.args.NRTNamespace)
if err != nil { if err != nil {
klog.Errorf("failed to advertise labels: %v", err) klog.Errorf("failed to advertise NodeResourceTopology: %w", err)
return &topologypb.NodeTopologyResponse{}, err return &topologypb.NodeTopologyResponse{}, err
} }
} }
@ -627,43 +626,23 @@ func stringToNsNames(cslist, ns string) []string {
return names return names
} }
func updateMap(data []*topologypb.CostInfo) []v1alpha1.CostInfo { func modifyCR(topoUpdaterZones []*v1alpha1.Zone) []v1alpha1.Zone {
ret := make([]v1alpha1.CostInfo, len(data))
for i, cost := range data {
ret[i] = v1alpha1.CostInfo{
Name: cost.Name,
Value: int(cost.Value),
}
}
return ret
}
func modifyCR(topoUpdaterZones []*topologypb.Zone) []v1alpha1.Zone {
zones := make([]v1alpha1.Zone, len(topoUpdaterZones)) zones := make([]v1alpha1.Zone, len(topoUpdaterZones))
// TODO: Avoid copying of data to allow returning the zone info // TODO: Avoid copying of data to allow returning the zone info
// directly in a compatible data type (i.e. []*v1alpha1.Zone). // directly in a compatible data type (i.e. []*v1alpha1.Zone).
for i, zone := range topoUpdaterZones { for i, zone := range topoUpdaterZones {
resInfo := make([]v1alpha1.ResourceInfo, len(zone.Resources))
for j, info := range zone.Resources {
resInfo[j] = v1alpha1.ResourceInfo{
Name: info.Name,
Allocatable: intstr.FromString(info.Allocatable),
Capacity: intstr.FromString(info.Capacity),
}
}
zones[i] = v1alpha1.Zone{ zones[i] = v1alpha1.Zone{
Name: zone.Name, Name: zone.Name,
Type: zone.Type, Type: zone.Type,
Parent: zone.Parent, Parent: zone.Parent,
Costs: updateMap(zone.Costs), Costs: zone.Costs,
Resources: resInfo, Resources: zone.Resources,
} }
} }
return zones return zones
} }
func (m *nfdMaster) updateCR(hostname string, tmpolicy []string, topoUpdaterZones []*topologypb.Zone, namespace string) error { func (m *nfdMaster) updateCR(hostname string, tmpolicy []string, topoUpdaterZones []*v1alpha1.Zone, namespace string) error {
cli, err := m.apihelper.GetTopologyClient() cli, err := m.apihelper.GetTopologyClient()
if err != nil { if err != nil {
return err return err

View file

@ -25,7 +25,6 @@ import (
topologyv1alpha1 "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/apis/topology/v1alpha1" topologyv1alpha1 "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/apis/topology/v1alpha1"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/klog/v2" "k8s.io/klog/v2"
podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1" podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1"
"sigs.k8s.io/node-feature-discovery/source" "sigs.k8s.io/node-feature-discovery/source"
@ -37,13 +36,15 @@ const (
) )
type nodeResources struct { type nodeResources struct {
perNUMACapacity map[int]map[v1.ResourceName]int64 perNUMAAllocatable map[int]map[v1.ResourceName]int64
// mapping: resourceName -> resourceID -> nodeID // mapping: resourceName -> resourceID -> nodeID
resourceID2NUMAID map[string]map[string]int resourceID2NUMAID map[string]map[string]int
topo *ghw.TopologyInfo topo *ghw.TopologyInfo
reservedCPUIDPerNUMA map[int][]string
} }
type resourceData struct { type resourceData struct {
available int64
allocatable int64 allocatable int64
capacity int64 capacity int64
} }
@ -74,21 +75,43 @@ func NewResourcesAggregator(podResourceClient podresourcesapi.PodResourcesLister
func NewResourcesAggregatorFromData(topo *ghw.TopologyInfo, resp *podresourcesapi.AllocatableResourcesResponse) ResourcesAggregator { func NewResourcesAggregatorFromData(topo *ghw.TopologyInfo, resp *podresourcesapi.AllocatableResourcesResponse) ResourcesAggregator {
allDevs := getContainerDevicesFromAllocatableResources(resp, topo) allDevs := getContainerDevicesFromAllocatableResources(resp, topo)
return &nodeResources{ return &nodeResources{
topo: topo, topo: topo,
resourceID2NUMAID: makeResourceMap(len(topo.Nodes), allDevs), resourceID2NUMAID: makeResourceMap(len(topo.Nodes), allDevs),
perNUMACapacity: makeNodeCapacity(allDevs), perNUMAAllocatable: makeNodeAllocatable(allDevs),
reservedCPUIDPerNUMA: makeReservedCPUMap(topo.Nodes, allDevs),
} }
} }
// Aggregate provides the mapping (numa zone name) -> Zone from the given PodResources. // Aggregate provides the mapping (numa zone name) -> Zone from the given PodResources.
func (noderesourceData *nodeResources) Aggregate(podResData []PodResources) topologyv1alpha1.ZoneList { func (noderesourceData *nodeResources) Aggregate(podResData []PodResources) topologyv1alpha1.ZoneList {
perNuma := make(map[int]map[v1.ResourceName]*resourceData) perNuma := make(map[int]map[v1.ResourceName]*resourceData)
for nodeID, nodeRes := range noderesourceData.perNUMACapacity { for nodeID := range noderesourceData.topo.Nodes {
perNuma[nodeID] = make(map[v1.ResourceName]*resourceData) nodeRes, ok := noderesourceData.perNUMAAllocatable[nodeID]
for resName, resCap := range nodeRes { if ok {
perNuma[nodeID][resName] = &resourceData{ perNuma[nodeID] = make(map[v1.ResourceName]*resourceData)
capacity: resCap, for resName, resCap := range nodeRes {
allocatable: resCap, if resName == "cpu" {
perNuma[nodeID][resName] = &resourceData{
allocatable: resCap,
available: resCap,
capacity: resCap + int64(len(noderesourceData.reservedCPUIDPerNUMA[nodeID])),
}
} else {
perNuma[nodeID][resName] = &resourceData{
allocatable: resCap,
available: resCap,
capacity: resCap,
}
}
}
// NUMA node doesn't have any allocatable resources, but yet it exists in the topology
// thus all its CPUs are reserved
} else {
perNuma[nodeID] = make(map[v1.ResourceName]*resourceData)
perNuma[nodeID]["cpu"] = &resourceData{
allocatable: int64(0),
available: int64(0),
capacity: int64(len(noderesourceData.reservedCPUIDPerNUMA[nodeID])),
} }
} }
} }
@ -96,12 +119,11 @@ func (noderesourceData *nodeResources) Aggregate(podResData []PodResources) topo
for _, podRes := range podResData { for _, podRes := range podResData {
for _, contRes := range podRes.Containers { for _, contRes := range podRes.Containers {
for _, res := range contRes.Resources { for _, res := range contRes.Resources {
noderesourceData.updateAllocatable(perNuma, res) noderesourceData.updateAvailable(perNuma, res)
} }
} }
} }
// zones := make([]topologyv1alpha1.Zone, 0)
zones := make(topologyv1alpha1.ZoneList, 0) zones := make(topologyv1alpha1.ZoneList, 0)
for nodeID, resList := range perNuma { for nodeID, resList := range perNuma {
zone := topologyv1alpha1.Zone{ zone := topologyv1alpha1.Zone{
@ -120,10 +142,12 @@ func (noderesourceData *nodeResources) Aggregate(podResData []PodResources) topo
for name, resData := range resList { for name, resData := range resList {
allocatableQty := *resource.NewQuantity(resData.allocatable, resource.DecimalSI) allocatableQty := *resource.NewQuantity(resData.allocatable, resource.DecimalSI)
capacityQty := *resource.NewQuantity(resData.capacity, resource.DecimalSI) capacityQty := *resource.NewQuantity(resData.capacity, resource.DecimalSI)
availableQty := *resource.NewQuantity(resData.available, resource.DecimalSI)
zone.Resources = append(zone.Resources, topologyv1alpha1.ResourceInfo{ zone.Resources = append(zone.Resources, topologyv1alpha1.ResourceInfo{
Name: name.String(), Name: name.String(),
Allocatable: intstr.FromString(allocatableQty.String()), Available: availableQty,
Capacity: intstr.FromString(capacityQty.String()), Allocatable: allocatableQty,
Capacity: capacityQty,
}) })
} }
zones = append(zones, zone) zones = append(zones, zone)
@ -168,9 +192,9 @@ func getContainerDevicesFromAllocatableResources(availRes *podresourcesapi.Alloc
return contDevs return contDevs
} }
// updateAllocatable computes the actually alloctable resources. // updateAvailable computes the actually available resources.
// This function assumes the allocatable resources are initialized to be equal to the capacity. // This function assumes the available resources are initialized to be equal to the allocatable.
func (noderesourceData *nodeResources) updateAllocatable(numaData map[int]map[v1.ResourceName]*resourceData, ri ResourceInfo) { func (noderesourceData *nodeResources) updateAvailable(numaData map[int]map[v1.ResourceName]*resourceData, ri ResourceInfo) {
for _, resID := range ri.Data { for _, resID := range ri.Data {
resName := string(ri.Name) resName := string(ri.Name)
resMap, ok := noderesourceData.resourceID2NUMAID[resName] resMap, ok := noderesourceData.resourceID2NUMAID[resName]
@ -183,7 +207,7 @@ func (noderesourceData *nodeResources) updateAllocatable(numaData map[int]map[v1
klog.Infof("unknown resource %q: %q", resName, resID) klog.Infof("unknown resource %q: %q", resName, resID)
continue continue
} }
numaData[nodeID][ri.Name].allocatable-- numaData[nodeID][ri.Name].available--
} }
} }
@ -192,25 +216,25 @@ func makeZoneName(nodeID int) string {
return fmt.Sprintf("node-%d", nodeID) return fmt.Sprintf("node-%d", nodeID)
} }
// makeNodeCapacity computes the node capacity as mapping (NUMA node ID) -> Resource -> Capacity (amount, int). // makeNodeAllocatable computes the node allocatable as mapping (NUMA node ID) -> Resource -> Allocatable (amount, int).
// The computation is done assuming all the resources to represent the capacity for are represented on a slice // The computation is done assuming all the resources to represent the allocatable for are represented on a slice
// of ContainerDevices. No special treatment is done for CPU IDs. See getContainerDevicesFromAllocatableResources. // of ContainerDevices. No special treatment is done for CPU IDs. See getContainerDevicesFromAllocatableResources.
func makeNodeCapacity(devices []*podresourcesapi.ContainerDevices) map[int]map[v1.ResourceName]int64 { func makeNodeAllocatable(devices []*podresourcesapi.ContainerDevices) map[int]map[v1.ResourceName]int64 {
perNUMACapacity := make(map[int]map[v1.ResourceName]int64) perNUMAAllocatable := make(map[int]map[v1.ResourceName]int64)
// initialize with the capacities // initialize with the capacities
for _, device := range devices { for _, device := range devices {
resourceName := device.GetResourceName() resourceName := device.GetResourceName()
for _, node := range device.GetTopology().GetNodes() { for _, node := range device.GetTopology().GetNodes() {
nodeID := int(node.GetID()) nodeID := int(node.GetID())
nodeRes, ok := perNUMACapacity[nodeID] nodeRes, ok := perNUMAAllocatable[nodeID]
if !ok { if !ok {
nodeRes = make(map[v1.ResourceName]int64) nodeRes = make(map[v1.ResourceName]int64)
} }
nodeRes[v1.ResourceName(resourceName)] += int64(len(device.GetDeviceIds())) nodeRes[v1.ResourceName(resourceName)] += int64(len(device.GetDeviceIds()))
perNUMACapacity[nodeID] = nodeRes perNUMAAllocatable[nodeID] = nodeRes
} }
} }
return perNUMACapacity return perNUMAAllocatable
} }
func MakeLogicalCoreIDToNodeIDMap(topo *ghw.TopologyInfo) map[int]int { func MakeLogicalCoreIDToNodeIDMap(topo *ghw.TopologyInfo) map[int]int {
@ -257,7 +281,7 @@ func makeCostsPerNumaNode(nodes []*ghw.TopologyNode, nodeIDSrc int) ([]topologyv
// TODO: this assumes there are no holes (= no offline node) in the distance vector // TODO: this assumes there are no holes (= no offline node) in the distance vector
nodeCosts = append(nodeCosts, topologyv1alpha1.CostInfo{ nodeCosts = append(nodeCosts, topologyv1alpha1.CostInfo{
Name: makeZoneName(nodeIDDst), Name: makeZoneName(nodeIDDst),
Value: dist, Value: int64(dist),
}) })
} }
return nodeCosts, nil return nodeCosts, nil
@ -271,3 +295,38 @@ func findNodeByID(nodes []*ghw.TopologyNode, nodeID int) *ghw.TopologyNode {
} }
return nil return nil
} }
func makeReservedCPUMap(nodes []*ghw.TopologyNode, devices []*podresourcesapi.ContainerDevices) map[int][]string {
reservedCPUsPerNuma := make(map[int][]string)
cpus := getCPUs(devices)
for _, node := range nodes {
nodeID := node.ID
for _, core := range node.Cores {
for _, cpu := range core.LogicalProcessors {
cpuID := fmt.Sprintf("%d", cpu)
_, ok := cpus[cpuID]
if !ok {
cpuIDList, ok := reservedCPUsPerNuma[nodeID]
if !ok {
cpuIDList = make([]string, 0)
}
cpuIDList = append(cpuIDList, cpuID)
reservedCPUsPerNuma[nodeID] = cpuIDList
}
}
}
}
return reservedCPUsPerNuma
}
func getCPUs(devices []*podresourcesapi.ContainerDevices) map[string]int {
cpuMap := make(map[string]int)
for _, device := range devices {
if device.GetResourceName() == "cpu" {
for _, devId := range device.DeviceIds {
cpuMap[devId] = int(device.Topology.Nodes[0].ID)
}
}
}
return cpuMap
}

View file

@ -26,7 +26,7 @@ import (
cmp "github.com/google/go-cmp/cmp" cmp "github.com/google/go-cmp/cmp"
. "github.com/smartystreets/goconvey/convey" . "github.com/smartystreets/goconvey/convey"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/api/resource"
topologyv1alpha1 "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/apis/topology/v1alpha1" topologyv1alpha1 "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/apis/topology/v1alpha1"
v1 "k8s.io/kubelet/pkg/apis/podresources/v1" v1 "k8s.io/kubelet/pkg/apis/podresources/v1"
@ -123,8 +123,10 @@ func TestResourcesAggregator(t *testing.T) {
}, },
}, },
}, },
// CPUId 0 and 1 are missing from the list below to simulate
// that they are not allocatable CPUs (kube-reserved or system-reserved)
CpuIds: []int64{ CpuIds: []int64{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
}, },
} }
@ -149,13 +151,15 @@ func TestResourcesAggregator(t *testing.T) {
Resources: topologyv1alpha1.ResourceInfoList{ Resources: topologyv1alpha1.ResourceInfoList{
topologyv1alpha1.ResourceInfo{ topologyv1alpha1.ResourceInfo{
Name: "cpu", Name: "cpu",
Allocatable: intstr.FromString("12"), Available: resource.MustParse("11"),
Capacity: intstr.FromString("12"), Allocatable: resource.MustParse("11"),
Capacity: resource.MustParse("12"),
}, },
topologyv1alpha1.ResourceInfo{ topologyv1alpha1.ResourceInfo{
Name: "fake.io/net", Name: "fake.io/net",
Allocatable: intstr.FromString("4"), Available: resource.MustParse("4"),
Capacity: intstr.FromString("4"), Allocatable: resource.MustParse("4"),
Capacity: resource.MustParse("4"),
}, },
}, },
}, },
@ -175,18 +179,21 @@ func TestResourcesAggregator(t *testing.T) {
Resources: topologyv1alpha1.ResourceInfoList{ Resources: topologyv1alpha1.ResourceInfoList{
topologyv1alpha1.ResourceInfo{ topologyv1alpha1.ResourceInfo{
Name: "cpu", Name: "cpu",
Allocatable: intstr.FromString("12"), Available: resource.MustParse("11"),
Capacity: intstr.FromString("12"), Allocatable: resource.MustParse("11"),
Capacity: resource.MustParse("12"),
}, },
topologyv1alpha1.ResourceInfo{ topologyv1alpha1.ResourceInfo{
Name: "fake.io/gpu", Name: "fake.io/gpu",
Allocatable: intstr.FromString("1"), Available: resource.MustParse("1"),
Capacity: intstr.FromString("1"), Allocatable: resource.MustParse("1"),
Capacity: resource.MustParse("1"),
}, },
topologyv1alpha1.ResourceInfo{ topologyv1alpha1.ResourceInfo{
Name: "fake.io/net", Name: "fake.io/net",
Allocatable: intstr.FromString("4"), Available: resource.MustParse("4"),
Capacity: intstr.FromString("4"), Allocatable: resource.MustParse("4"),
Capacity: resource.MustParse("4"),
}, },
}, },
}, },
@ -250,8 +257,10 @@ func TestResourcesAggregator(t *testing.T) {
}, },
}, },
}, },
// CPUId 0 is missing from the list below to simulate
// that it not allocatable (kube-reserved or system-reserved)
CpuIds: []int64{ CpuIds: []int64{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
}, },
} }
@ -298,13 +307,15 @@ func TestResourcesAggregator(t *testing.T) {
Resources: topologyv1alpha1.ResourceInfoList{ Resources: topologyv1alpha1.ResourceInfoList{
topologyv1alpha1.ResourceInfo{ topologyv1alpha1.ResourceInfo{
Name: "cpu", Name: "cpu",
Allocatable: intstr.FromString("12"), Available: resource.MustParse("11"),
Capacity: intstr.FromString("12"), Allocatable: resource.MustParse("11"),
Capacity: resource.MustParse("12"),
}, },
topologyv1alpha1.ResourceInfo{ topologyv1alpha1.ResourceInfo{
Name: "fake.io/net", Name: "fake.io/net",
Allocatable: intstr.FromString("1"), Available: resource.MustParse("1"),
Capacity: intstr.FromString("1"), Allocatable: resource.MustParse("1"),
Capacity: resource.MustParse("1"),
}, },
}, },
}, },
@ -324,18 +335,21 @@ func TestResourcesAggregator(t *testing.T) {
Resources: topologyv1alpha1.ResourceInfoList{ Resources: topologyv1alpha1.ResourceInfoList{
topologyv1alpha1.ResourceInfo{ topologyv1alpha1.ResourceInfo{
Name: "cpu", Name: "cpu",
Allocatable: intstr.FromString("10"), Available: resource.MustParse("10"),
Capacity: intstr.FromString("12"), Allocatable: resource.MustParse("12"),
Capacity: resource.MustParse("12"),
}, },
topologyv1alpha1.ResourceInfo{ topologyv1alpha1.ResourceInfo{
Name: "fake.io/gpu", Name: "fake.io/gpu",
Allocatable: intstr.FromString("1"), Available: resource.MustParse("1"),
Capacity: intstr.FromString("1"), Allocatable: resource.MustParse("1"),
Capacity: resource.MustParse("1"),
}, },
topologyv1alpha1.ResourceInfo{ topologyv1alpha1.ResourceInfo{
Name: "fake.io/net", Name: "fake.io/net",
Allocatable: intstr.FromString("0"), Available: resource.MustParse("0"),
Capacity: intstr.FromString("1"), Allocatable: resource.MustParse("1"),
Capacity: resource.MustParse("1"),
}, },
}, },
}, },

View file

@ -15,17 +15,16 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.25.0 // protoc-gen-go v1.23.0
// protoc v3.6.1 // protoc v3.17.3
// source: pkg/topologyupdater/topology-updater.proto // source: pkg/topologyupdater/topology-updater.proto
//option go_package = "topologyupdater";
package topologyupdater package topologyupdater
import ( import (
context "context" context "context"
proto "github.com/golang/protobuf/proto" proto "github.com/golang/protobuf/proto"
v1alpha1 "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/apis/topology/v1alpha1"
grpc "google.golang.org/grpc" grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes" codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status" status "google.golang.org/grpc/status"
@ -51,10 +50,10 @@ type NodeTopologyRequest struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
NfdVersion string `protobuf:"bytes,1,opt,name=nfd_version,json=nfdVersion,proto3" json:"nfd_version,omitempty"` NfdVersion string `protobuf:"bytes,1,opt,name=nfd_version,json=nfdVersion,proto3" json:"nfd_version,omitempty"`
NodeName string `protobuf:"bytes,2,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"` NodeName string `protobuf:"bytes,2,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"`
TopologyPolicies []string `protobuf:"bytes,3,rep,name=topology_policies,json=topologyPolicies,proto3" json:"topology_policies,omitempty"` TopologyPolicies []string `protobuf:"bytes,3,rep,name=topology_policies,json=topologyPolicies,proto3" json:"topology_policies,omitempty"`
Zones []*Zone `protobuf:"bytes,4,rep,name=zones,proto3" json:"zones,omitempty"` Zones []*v1alpha1.Zone `protobuf:"bytes,4,rep,name=zones,proto3" json:"zones,omitempty"`
} }
func (x *NodeTopologyRequest) Reset() { func (x *NodeTopologyRequest) Reset() {
@ -110,273 +109,13 @@ func (x *NodeTopologyRequest) GetTopologyPolicies() []string {
return nil return nil
} }
func (x *NodeTopologyRequest) GetZones() []*Zone { func (x *NodeTopologyRequest) GetZones() []*v1alpha1.Zone {
if x != nil { if x != nil {
return x.Zones return x.Zones
} }
return nil return nil
} }
type Zone struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
Parent string `protobuf:"bytes,3,opt,name=parent,proto3" json:"parent,omitempty"`
Costs []*CostInfo `protobuf:"bytes,4,rep,name=costs,proto3" json:"costs,omitempty"`
Attributes []*AttributeInfo `protobuf:"bytes,5,rep,name=attributes,proto3" json:"attributes,omitempty"`
Resources []*ResourceInfo `protobuf:"bytes,6,rep,name=resources,proto3" json:"resources,omitempty"`
}
func (x *Zone) Reset() {
*x = Zone{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_topologyupdater_topology_updater_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Zone) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Zone) ProtoMessage() {}
func (x *Zone) ProtoReflect() protoreflect.Message {
mi := &file_pkg_topologyupdater_topology_updater_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Zone.ProtoReflect.Descriptor instead.
func (*Zone) Descriptor() ([]byte, []int) {
return file_pkg_topologyupdater_topology_updater_proto_rawDescGZIP(), []int{1}
}
func (x *Zone) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *Zone) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *Zone) GetParent() string {
if x != nil {
return x.Parent
}
return ""
}
func (x *Zone) GetCosts() []*CostInfo {
if x != nil {
return x.Costs
}
return nil
}
func (x *Zone) GetAttributes() []*AttributeInfo {
if x != nil {
return x.Attributes
}
return nil
}
func (x *Zone) GetResources() []*ResourceInfo {
if x != nil {
return x.Resources
}
return nil
}
type CostInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Value int32 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"`
}
func (x *CostInfo) Reset() {
*x = CostInfo{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_topologyupdater_topology_updater_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CostInfo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CostInfo) ProtoMessage() {}
func (x *CostInfo) ProtoReflect() protoreflect.Message {
mi := &file_pkg_topologyupdater_topology_updater_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CostInfo.ProtoReflect.Descriptor instead.
func (*CostInfo) Descriptor() ([]byte, []int) {
return file_pkg_topologyupdater_topology_updater_proto_rawDescGZIP(), []int{2}
}
func (x *CostInfo) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *CostInfo) GetValue() int32 {
if x != nil {
return x.Value
}
return 0
}
type AttributeInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
}
func (x *AttributeInfo) Reset() {
*x = AttributeInfo{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_topologyupdater_topology_updater_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *AttributeInfo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AttributeInfo) ProtoMessage() {}
func (x *AttributeInfo) ProtoReflect() protoreflect.Message {
mi := &file_pkg_topologyupdater_topology_updater_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AttributeInfo.ProtoReflect.Descriptor instead.
func (*AttributeInfo) Descriptor() ([]byte, []int) {
return file_pkg_topologyupdater_topology_updater_proto_rawDescGZIP(), []int{3}
}
func (x *AttributeInfo) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *AttributeInfo) GetValue() string {
if x != nil {
return x.Value
}
return ""
}
type ResourceInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Allocatable string `protobuf:"bytes,2,opt,name=allocatable,proto3" json:"allocatable,omitempty"`
Capacity string `protobuf:"bytes,3,opt,name=capacity,proto3" json:"capacity,omitempty"`
}
func (x *ResourceInfo) Reset() {
*x = ResourceInfo{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_topologyupdater_topology_updater_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ResourceInfo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ResourceInfo) ProtoMessage() {}
func (x *ResourceInfo) ProtoReflect() protoreflect.Message {
mi := &file_pkg_topologyupdater_topology_updater_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ResourceInfo.ProtoReflect.Descriptor instead.
func (*ResourceInfo) Descriptor() ([]byte, []int) {
return file_pkg_topologyupdater_topology_updater_proto_rawDescGZIP(), []int{4}
}
func (x *ResourceInfo) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *ResourceInfo) GetAllocatable() string {
if x != nil {
return x.Allocatable
}
return ""
}
func (x *ResourceInfo) GetCapacity() string {
if x != nil {
return x.Capacity
}
return ""
}
type NodeTopologyResponse struct { type NodeTopologyResponse struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -386,7 +125,7 @@ type NodeTopologyResponse struct {
func (x *NodeTopologyResponse) Reset() { func (x *NodeTopologyResponse) Reset() {
*x = NodeTopologyResponse{} *x = NodeTopologyResponse{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_pkg_topologyupdater_topology_updater_proto_msgTypes[5] mi := &file_pkg_topologyupdater_topology_updater_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -399,7 +138,7 @@ func (x *NodeTopologyResponse) String() string {
func (*NodeTopologyResponse) ProtoMessage() {} func (*NodeTopologyResponse) ProtoMessage() {}
func (x *NodeTopologyResponse) ProtoReflect() protoreflect.Message { func (x *NodeTopologyResponse) ProtoReflect() protoreflect.Message {
mi := &file_pkg_topologyupdater_topology_updater_proto_msgTypes[5] mi := &file_pkg_topologyupdater_topology_updater_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -412,7 +151,7 @@ func (x *NodeTopologyResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use NodeTopologyResponse.ProtoReflect.Descriptor instead. // Deprecated: Use NodeTopologyResponse.ProtoReflect.Descriptor instead.
func (*NodeTopologyResponse) Descriptor() ([]byte, []int) { func (*NodeTopologyResponse) Descriptor() ([]byte, []int) {
return file_pkg_topologyupdater_topology_updater_proto_rawDescGZIP(), []int{5} return file_pkg_topologyupdater_topology_updater_proto_rawDescGZIP(), []int{1}
} }
var File_pkg_topologyupdater_topology_updater_proto protoreflect.FileDescriptor var File_pkg_topologyupdater_topology_updater_proto protoreflect.FileDescriptor
@ -421,56 +160,37 @@ var file_pkg_topologyupdater_topology_updater_proto_rawDesc = []byte{
0x0a, 0x2a, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x75, 0x70, 0x0a, 0x2a, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x75, 0x70,
0x64, 0x61, 0x74, 0x65, 0x72, 0x2f, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x2d, 0x75, 0x64, 0x61, 0x74, 0x65, 0x72, 0x2f, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x2d, 0x75,
0x70, 0x64, 0x61, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x74, 0x6f, 0x70, 0x64, 0x61, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x74, 0x6f,
0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x72, 0x22, 0xad, 0x01, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x72, 0x1a, 0x66, 0x67,
0x0a, 0x13, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x38, 0x73, 0x74, 0x6f, 0x70,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x66, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x61, 0x77, 0x61, 0x72, 0x65, 0x73, 0x63, 0x68, 0x65, 0x64, 0x77,
0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x66, 0x64, 0x56, 0x67, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x74, 0x6f,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x2d, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61,
0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x70, 0x69, 0x73, 0x2f, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x2f, 0x76, 0x31, 0x61,
0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2e,
0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa6, 0x01, 0x0a, 0x13, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x6f,
0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a,
0x12, 0x2b, 0x0a, 0x05, 0x7a, 0x6f, 0x6e, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x6e, 0x66, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x66, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b,
0x72, 0x2e, 0x5a, 0x6f, 0x6e, 0x65, 0x52, 0x05, 0x7a, 0x6f, 0x6e, 0x65, 0x73, 0x22, 0xf4, 0x01, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0a, 0x04, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x74,
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73,
0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79,
0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x05, 0x7a, 0x6f, 0x6e, 0x65,
0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x61, 0x31, 0x2e, 0x5a, 0x6f, 0x6e, 0x65, 0x52, 0x05, 0x7a, 0x6f, 0x6e, 0x65, 0x73, 0x22, 0x16,
0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x0a, 0x14, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65,
0x52, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x3e, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x71, 0x0a, 0x0c, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x6f,
0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x61, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x72, 0x2e, 0x41, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x24, 0x2e, 0x74,
0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x72, 0x2e, 0x4e,
0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x6f, 0x64, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
0x72, 0x63, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x6f, 0x70, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x75, 0x70, 0x64,
0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x61, 0x74, 0x65, 0x72, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x38, 0x5a, 0x36, 0x73, 0x69, 0x67,
0x72, 0x63, 0x65, 0x73, 0x22, 0x34, 0x0a, 0x08, 0x43, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x2e, 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2d, 0x66, 0x65,
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2d, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2f,
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x75, 0x70, 0x64, 0x61,
0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x39, 0x0a, 0x0d, 0x41, 0x74, 0x74, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x60, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x6c, 0x6c,
0x6f, 0x63, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63,
0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63,
0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x22, 0x16, 0x0a, 0x14, 0x4e, 0x6f, 0x64, 0x65, 0x54,
0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32,
0x71, 0x0a, 0x0c, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12,
0x61, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x6f, 0x70,
0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x24, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79,
0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x72, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x6f, 0x70, 0x6f,
0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x74, 0x6f,
0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x72, 0x2e, 0x4e, 0x6f,
0x64, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -485,27 +205,21 @@ func file_pkg_topologyupdater_topology_updater_proto_rawDescGZIP() []byte {
return file_pkg_topologyupdater_topology_updater_proto_rawDescData return file_pkg_topologyupdater_topology_updater_proto_rawDescData
} }
var file_pkg_topologyupdater_topology_updater_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_pkg_topologyupdater_topology_updater_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_pkg_topologyupdater_topology_updater_proto_goTypes = []interface{}{ var file_pkg_topologyupdater_topology_updater_proto_goTypes = []interface{}{
(*NodeTopologyRequest)(nil), // 0: topologyupdater.NodeTopologyRequest (*NodeTopologyRequest)(nil), // 0: topologyupdater.NodeTopologyRequest
(*Zone)(nil), // 1: topologyupdater.Zone (*NodeTopologyResponse)(nil), // 1: topologyupdater.NodeTopologyResponse
(*CostInfo)(nil), // 2: topologyupdater.CostInfo (*v1alpha1.Zone)(nil), // 2: v1alpha1.Zone
(*AttributeInfo)(nil), // 3: topologyupdater.AttributeInfo
(*ResourceInfo)(nil), // 4: topologyupdater.ResourceInfo
(*NodeTopologyResponse)(nil), // 5: topologyupdater.NodeTopologyResponse
} }
var file_pkg_topologyupdater_topology_updater_proto_depIdxs = []int32{ var file_pkg_topologyupdater_topology_updater_proto_depIdxs = []int32{
1, // 0: topologyupdater.NodeTopologyRequest.zones:type_name -> topologyupdater.Zone 2, // 0: topologyupdater.NodeTopologyRequest.zones:type_name -> v1alpha1.Zone
2, // 1: topologyupdater.Zone.costs:type_name -> topologyupdater.CostInfo 0, // 1: topologyupdater.NodeTopology.UpdateNodeTopology:input_type -> topologyupdater.NodeTopologyRequest
3, // 2: topologyupdater.Zone.attributes:type_name -> topologyupdater.AttributeInfo 1, // 2: topologyupdater.NodeTopology.UpdateNodeTopology:output_type -> topologyupdater.NodeTopologyResponse
4, // 3: topologyupdater.Zone.resources:type_name -> topologyupdater.ResourceInfo 2, // [2:3] is the sub-list for method output_type
0, // 4: topologyupdater.NodeTopology.UpdateNodeTopology:input_type -> topologyupdater.NodeTopologyRequest 1, // [1:2] is the sub-list for method input_type
5, // 5: topologyupdater.NodeTopology.UpdateNodeTopology:output_type -> topologyupdater.NodeTopologyResponse 1, // [1:1] is the sub-list for extension type_name
5, // [5:6] is the sub-list for method output_type 1, // [1:1] is the sub-list for extension extendee
4, // [4:5] is the sub-list for method input_type 0, // [0:1] is the sub-list for field type_name
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
} }
func init() { file_pkg_topologyupdater_topology_updater_proto_init() } func init() { file_pkg_topologyupdater_topology_updater_proto_init() }
@ -527,54 +241,6 @@ func file_pkg_topologyupdater_topology_updater_proto_init() {
} }
} }
file_pkg_topologyupdater_topology_updater_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { file_pkg_topologyupdater_topology_updater_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Zone); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_topologyupdater_topology_updater_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CostInfo); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_topologyupdater_topology_updater_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AttributeInfo); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_topologyupdater_topology_updater_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ResourceInfo); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_topologyupdater_topology_updater_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeTopologyResponse); i { switch v := v.(*NodeTopologyResponse); i {
case 0: case 0:
return &v.state return &v.state
@ -593,7 +259,7 @@ func file_pkg_topologyupdater_topology_updater_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_pkg_topologyupdater_topology_updater_proto_rawDesc, RawDescriptor: file_pkg_topologyupdater_topology_updater_proto_rawDesc,
NumEnums: 0, NumEnums: 0,
NumMessages: 6, NumMessages: 2,
NumExtensions: 0, NumExtensions: 0,
NumServices: 1, NumServices: 1,
}, },

View file

@ -15,7 +15,8 @@ limitations under the License.
*/ */
syntax = "proto3"; syntax = "proto3";
//option go_package = "topologyupdater"; option go_package = "sigs.k8s.io/node-feature-discovery/pkg/topologyupdater";
import "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/apis/topology/v1alpha1/generated.proto";
package topologyupdater; package topologyupdater;
@ -27,33 +28,7 @@ message NodeTopologyRequest {
string nfd_version = 1; string nfd_version = 1;
string node_name = 2; string node_name = 2;
repeated string topology_policies = 3; repeated string topology_policies = 3;
repeated Zone zones = 4; repeated v1alpha1.Zone zones = 4;
}
message Zone {
string name = 1;
string type = 2;
string parent = 3;
repeated CostInfo costs = 4;
repeated AttributeInfo attributes = 5;
repeated ResourceInfo resources = 6;
}
message CostInfo {
string name = 1;
int32 value = 2 ;
}
message AttributeInfo {
string name = 1;
string value = 2 ;
}
message ResourceInfo {
string name = 1;
string allocatable = 2;
string capacity = 3;
} }
message NodeTopologyResponse { message NodeTopologyResponse {