Skip to content

Commit

Permalink
Remove size/fromHardware endpoint (#524)
Browse files Browse the repository at this point in the history
  • Loading branch information
majst01 committed May 7, 2024
1 parent 9aa6fc7 commit d295a05
Show file tree
Hide file tree
Showing 8 changed files with 14 additions and 186 deletions.
6 changes: 3 additions & 3 deletions cmd/metal-api/internal/datastore/size.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ func (rs *RethinkStore) UpdateSize(oldSize *metal.Size, newSize *metal.Size) err
}

// FromHardware tries to find a size which matches the given hardware specs.
func (rs *RethinkStore) FromHardware(hw metal.MachineHardware) (*metal.Size, []*metal.SizeMatchingLog, error) {
func (rs *RethinkStore) FromHardware(hw metal.MachineHardware) (*metal.Size, error) {
sz, err := rs.ListSizes()
if err != nil {
return nil, nil, err
return nil, err
}
if len(sz) < 1 {
// this should not happen, so we do not return a notfound
return nil, nil, errors.New("no sizes found in database")
return nil, errors.New("no sizes found in database")
}
var sizes metal.Sizes
for _, s := range sz {
Expand Down
2 changes: 1 addition & 1 deletion cmd/metal-api/internal/datastore/size_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ func TestRethinkStore_FromHardware(t *testing.T) {
for i := range tests {
tt := tests[i]
t.Run(tt.name, func(t *testing.T) {
got, _, err := tt.rs.FromHardware(tt.hw)
got, err := tt.rs.FromHardware(tt.hw)
if (err != nil) != tt.wantErr {
t.Errorf("RethinkStore.FromHardware() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down
2 changes: 1 addition & 1 deletion cmd/metal-api/internal/grpc/boot-service.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func (b *BootService) Register(ctx context.Context, req *v1.BootServiceRegisterR
MetalGPUs: gpus,
}

size, _, err := b.ds.FromHardware(machineHardware)
size, err := b.ds.FromHardware(machineHardware)
if err != nil {
size = metal.UnknownSize()
b.log.Error("no size found for hardware, defaulting to unknown size", "hardware", machineHardware, "error", err)
Expand Down
47 changes: 8 additions & 39 deletions cmd/metal-api/internal/metal/size.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,68 +74,53 @@ func UnknownSize() *Size {

// Matches returns true if the given machine hardware is inside the min/max values of the
// constraint.
func (c *Constraint) Matches(hw MachineHardware) (ConstraintMatchingLog, bool) {
logentryFmt := fmt.Sprintf("%%d >= %d && %%d <= %d", c.Min, c.Max)
cml := ConstraintMatchingLog{Constraint: *c, Log: fmt.Sprintf("no constraint matching %q", c.Type)}
func (c *Constraint) Matches(hw MachineHardware) bool {
res := false
switch c.Type {
case CoreConstraint:
res = uint64(hw.CPUCores) >= c.Min && uint64(hw.CPUCores) <= c.Max
cml.Log = fmt.Sprintf(logentryFmt, hw.CPUCores, hw.CPUCores)
case MemoryConstraint:
res = hw.Memory >= c.Min && hw.Memory <= c.Max
cml.Log = fmt.Sprintf(logentryFmt, hw.Memory, hw.Memory)
case StorageConstraint:
res = hw.DiskCapacity() >= c.Min && hw.DiskCapacity() <= c.Max
cml.Log = fmt.Sprintf(logentryFmt, hw.DiskCapacity(), hw.DiskCapacity())
case GPUConstraint:
for model, count := range hw.GPUModels() {
idMatches, err := filepath.Match(c.Identifier, model)
if err != nil {
cml.Log = fmt.Sprintf("cannot match gpu model:%v", err)
return cml, false
return false
}
res = count >= c.Min && count <= c.Max && idMatches
if res {
break
}
}

cml.Log = fmt.Sprintf("existing gpus:%#v required gpus:%s count %d-%d", hw.MetalGPUs, c.Identifier, c.Min, c.Max)
}
cml.Match = res
return cml, res
return res
}

// FromHardware searches a Size for given hardware specs. It will search
// for a size where the constraints matches the given hardware.
func (sz Sizes) FromHardware(hardware MachineHardware) (*Size, []*SizeMatchingLog, error) {
func (sz Sizes) FromHardware(hardware MachineHardware) (*Size, error) {
var found []Size
matchlog := make([]*SizeMatchingLog, 0)
var matchedlog *SizeMatchingLog
nextsize:
for _, s := range sz {
ml := &SizeMatchingLog{Name: s.ID, Match: false}
matchlog = append(matchlog, ml)
for _, c := range s.Constraints {
lg, match := c.Matches(hardware)
ml.Constraints = append(ml.Constraints, lg)
match := c.Matches(hardware)
if !match {
continue nextsize
}
}
ml.Match = true
matchedlog = ml
found = append(found, s)
}

if len(found) == 0 {
return nil, matchlog, NotFound("no size found for hardware (%s)", hardware.ReadableSpec())
return nil, NotFound("no size found for hardware (%s)", hardware.ReadableSpec())
}
if len(found) > 1 {
return nil, matchlog, fmt.Errorf("%d sizes found for hardware (%s)", len(found), hardware.ReadableSpec())
return nil, fmt.Errorf("%d sizes found for hardware (%s)", len(found), hardware.ReadableSpec())
}
return &found[0], []*SizeMatchingLog{matchedlog}, nil
return &found[0], nil
}

func (s *Size) overlaps(so *Size) bool {
Expand Down Expand Up @@ -293,19 +278,3 @@ func (rs *Reservations) Validate(partitions PartitionMap, projects map[string]*m

return nil
}

// A ConstraintMatchingLog is used do return a log message to the caller
// beside the constraint itself.
type ConstraintMatchingLog struct {
Constraint Constraint
Match bool
Log string
}

// A SizeMatchingLog returns information about a list of constraints.
type SizeMatchingLog struct {
Name string
Log string
Match bool
Constraints []ConstraintMatchingLog
}
2 changes: 1 addition & 1 deletion cmd/metal-api/internal/metal/size_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ func TestSizes_FromHardware(t *testing.T) {
for i := range tests {
tt := tests[i]
t.Run(tt.name, func(t *testing.T) {
got, _, err := tt.sz.FromHardware(tt.args.hardware)
got, err := tt.sz.FromHardware(tt.args.hardware)
if (err != nil) != tt.wantErr {
t.Errorf("Sizes.FromHardware() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down
34 changes: 0 additions & 34 deletions cmd/metal-api/internal/service/size-service.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package service

import (
"errors"
"fmt"
"log/slog"
"net/http"
Expand Down Expand Up @@ -115,16 +114,6 @@ func (r *sizeResource) webService() *restful.WebService {
Returns(http.StatusConflict, "Conflict", httperrors.HTTPErrorResponse{}).
DefaultReturns("Error", httperrors.HTTPErrorResponse{}))

ws.Route(ws.POST("/from-hardware").
To(r.fromHardware).
Operation("fromHardware").
Doc("Searches all sizes for one to match the given hardwarespecs. If nothing is found, a list of entries is returned which describe the constraint which did not match").
Metadata(restfulspec.KeyOpenAPITags, tags).
Metadata(auditing.Exclude, true).
Reads(v1.MachineHardware{}).
Returns(http.StatusOK, "OK", v1.SizeMatchingLog{}).
DefaultReturns("Error", httperrors.HTTPErrorResponse{}))

return ws
}

Expand Down Expand Up @@ -427,29 +416,6 @@ func (r *sizeResource) updateSize(request *restful.Request, response *restful.Re
r.send(request, response, http.StatusOK, v1.NewSizeResponse(&newSize))
}

func (r *sizeResource) fromHardware(request *restful.Request, response *restful.Response) {
var requestPayload v1.MachineHardware
err := request.ReadEntity(&requestPayload)
if err != nil {
r.sendError(request, response, httperrors.BadRequest(err))
return
}

hw := v1.NewMetalMachineHardware(&requestPayload)
_, lg, err := r.ds.FromHardware(hw)
if err != nil {
r.sendError(request, response, defaultError(err))
return
}

if len(lg) < 1 {
r.sendError(request, response, httperrors.UnprocessableEntity(errors.New("size matching log is empty")))
return
}

r.send(request, response, http.StatusOK, v1.NewSizeMatchingLog(lg[0]))
}

func (r *sizeResource) listSizeReservations(request *restful.Request, response *restful.Response) {
ss, err := r.ds.ListSizes()
if err != nil {
Expand Down
22 changes: 0 additions & 22 deletions cmd/metal-api/internal/service/v1/size.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,28 +68,6 @@ type SizeMatchingLog struct {
Constraints []SizeConstraintMatchingLog `json:"constraints"`
}

func NewSizeMatchingLog(m *metal.SizeMatchingLog) *SizeMatchingLog {
constraints := []SizeConstraintMatchingLog{}
for i := range m.Constraints {
constraint := SizeConstraintMatchingLog{
Constraint: SizeConstraint{
Type: m.Constraints[i].Constraint.Type,
Min: m.Constraints[i].Constraint.Min,
Max: m.Constraints[i].Constraint.Max,
},
Match: m.Constraints[i].Match,
Log: m.Constraints[i].Log,
}
constraints = append(constraints, constraint)
}
return &SizeMatchingLog{
Name: m.Name,
Match: m.Match,
Log: m.Log,
Constraints: constraints,
}
}

func NewSizeResponse(s *metal.Size) *SizeResponse {
if s == nil {
return nil
Expand Down
85 changes: 0 additions & 85 deletions spec/metal-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -4503,27 +4503,6 @@
"type"
]
},
"v1.SizeConstraintMatchingLog": {
"properties": {
"constraint": {
"$ref": "#/definitions/v1.SizeConstraint",
"description": "the size constraint to which this log relates to"
},
"log": {
"description": "a string representation of the matching condition",
"type": "string"
},
"match": {
"description": "indicates whether the constraint matched or not",
"type": "boolean"
}
},
"required": [
"constraint",
"log",
"match"
]
},
"v1.SizeCreateRequest": {
"properties": {
"constraints": {
Expand Down Expand Up @@ -4663,31 +4642,6 @@
"id"
]
},
"v1.SizeMatchingLog": {
"properties": {
"constraints": {
"items": {
"$ref": "#/definitions/v1.SizeConstraintMatchingLog"
},
"type": "array"
},
"log": {
"type": "string"
},
"match": {
"type": "boolean"
},
"name": {
"type": "string"
}
},
"required": [
"constraints",
"log",
"match",
"name"
]
},
"v1.SizeReservation": {
"properties": {
"amount": {
Expand Down Expand Up @@ -9077,45 +9031,6 @@
]
}
},
"/v1/size/from-hardware": {
"post": {
"consumes": [
"application/json"
],
"operationId": "fromHardware",
"parameters": [
{
"in": "body",
"name": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1.MachineHardware"
}
}
],
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/v1.SizeMatchingLog"
}
},
"default": {
"description": "Error",
"schema": {
"$ref": "#/definitions/httperrors.HTTPErrorResponse"
}
}
},
"summary": "Searches all sizes for one to match the given hardwarespecs. If nothing is found, a list of entries is returned which describe the constraint which did not match",
"tags": [
"size"
]
}
},
"/v1/size/reservations": {
"post": {
"consumes": [
Expand Down

0 comments on commit d295a05

Please sign in to comment.