Skip to content

Commit

Permalink
compute: Don't munge scheduler hints
Browse files Browse the repository at this point in the history
Do as we did for the block storage equivalent before and unmunge the
scheduler hints options from the general server create options.

Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
  • Loading branch information
stephenfin committed May 20, 2024
1 parent 0811a76 commit d520ff8
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 120 deletions.
24 changes: 12 additions & 12 deletions internal/acceptance/openstack/compute/v2/compute.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func CreateBootableVolumeServer(t *testing.T, client *gophercloud.ServiceClient,
createOpts.ImageRef = blockDevices[0].UUID
}

server, err = servers.Create(context.TODO(), client, createOpts).Extract()
server, err = servers.Create(context.TODO(), client, createOpts, nil).Extract()

if err != nil {
return server, err
Expand Down Expand Up @@ -249,7 +249,7 @@ func CreateMultiEphemeralServer(t *testing.T, client *gophercloud.ServiceClient,
BlockDevice: blockDevices,
}

server, err = servers.Create(context.TODO(), client, createOpts).Extract()
server, err = servers.Create(context.TODO(), client, createOpts, nil).Extract()

if err != nil {
return server, err
Expand Down Expand Up @@ -389,7 +389,7 @@ func CreateServer(t *testing.T, client *gophercloud.ServiceClient) (*servers.Ser
Contents: []byte("hello world"),
},
},
}).Extract()
}, nil).Extract()
if err != nil {
return server, err
}
Expand Down Expand Up @@ -443,7 +443,7 @@ func CreateMicroversionServer(t *testing.T, client *gophercloud.ServiceClient) (
Metadata: map[string]string{
"abc": "def",
},
}).Extract()
}, nil).Extract()
if err != nil {
return server, err
}
Expand Down Expand Up @@ -497,7 +497,7 @@ func CreateServerWithoutImageRef(t *testing.T, client *gophercloud.ServiceClient
Contents: []byte("hello world"),
},
},
}).Extract()
}, nil).Extract()
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -544,7 +544,7 @@ func CreateServerWithTags(t *testing.T, client *gophercloud.ServiceClient, netwo
},
},
Tags: []string{"tag1", "tag2"},
}).Extract()
}, nil).Extract()
if err != nil {
return server, err
}
Expand Down Expand Up @@ -643,12 +643,12 @@ func CreateServerInServerGroup(t *testing.T, client *gophercloud.ServiceClient,
Networks: []servers.Network{
{UUID: networkID},
},
SchedulerHints: servers.SchedulerHints{
Group: serverGroup.ID,
},
}
schedulerHintOpts := servers.SchedulerHintOpts{
Group: serverGroup.ID,
}

server, err := servers.Create(context.TODO(), client, serverCreateOpts).Extract()
server, err := servers.Create(context.TODO(), client, serverCreateOpts, schedulerHintOpts).Extract()
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -697,7 +697,7 @@ func CreateServerWithPublicKey(t *testing.T, client *gophercloud.ServiceClient,
server, err := servers.Create(context.TODO(), client, keypairs.CreateOptsExt{
CreateOptsBuilder: serverCreateOpts,
KeyName: keyPairName,
}).Extract()
}, nil).Extract()
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1056,7 +1056,7 @@ func CreateServerNoNetwork(t *testing.T, client *gophercloud.ServiceClient) (*se
Contents: []byte("hello world"),
},
},
}).Extract()
}, nil).Extract()
if err != nil {
return server, err
}
Expand Down
63 changes: 33 additions & 30 deletions openstack/compute/v2/servers/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,59 +53,62 @@ Example to Create a Server
FlavorRef: "flavor-uuid",
}
server, err := servers.Create(context.TODO(), computeClient, createOpts).Extract()
server, err := servers.Create(context.TODO(), computeClient, createOpts, nil).Extract()
if err != nil {
panic(err)
}
Example to Add a Server to a Server Group
schedulerHintOpts := servers.SchedulerHintOpts{
Group: "servergroup-uuid",
}
createOpts := servers.CreateOpts{
Name: "server_name",
ImageRef: "image-uuid",
FlavorRef: "flavor-uuid",
SchedulerHints: servers.SchedulerHints{
Group: "servergroup-uuid",
},
Name: "server_name",
ImageRef: "image-uuid",
FlavorRef: "flavor-uuid",
}
server, err := servers.Create(context.TODO(), computeClient, createOpts).Extract()
server, err := servers.Create(context.TODO(), computeClient, createOpts, schedulerHintOpts).Extract()
if err != nil {
panic(err)
}
Example to Place Server B on a Different Host than Server A
schedulerHintOpts := servers.SchedulerHintOpts{
DifferentHost: []string{
"server-a-uuid",
}
}
createOpts := servers.CreateOpts{
Name: "server_name",
ImageRef: "image-uuid",
FlavorRef: "flavor-uuid",
SchedulerHints: servers.SchedulerHints{
DifferentHost: []string{
"server-a-uuid",
}
},
Name: "server_b",
ImageRef: "image-uuid",
FlavorRef: "flavor-uuid",
}
server, err := servers.Create(context.TODO(), computeClient, createOpts).Extract()
server, err := servers.Create(context.TODO(), computeClient, createOpts, schedulerHintOpts).Extract()
if err != nil {
panic(err)
}
Example to Place Server B on the Same Host as Server A
schedulerHintOpts := servers.SchedulerHintOpts{
SameHost: []string{
"server-a-uuid",
}
}
createOpts := servers.CreateOpts{
Name: "server_name",
ImageRef: "image-uuid",
FlavorRef: "flavor-uuid",
SchedulerHints: servers.SchedulerHints{
SameHost: []string{
"server-a-uuid",
}
},
Name: "server_b",
ImageRef: "image-uuid",
FlavorRef: "flavor-uuid",
}
server, err := servers.Create(context.TODO(), computeClient, createOpts).Extract()
server, err := servers.Create(context.TODO(), computeClient, createOpts, schedulerHintOpts).Extract()
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -133,7 +136,7 @@ a server without using block device mappings.
BlockDevice: blockDevices,
}
server, err := servers.Create(context.TODO(), client, createOpts).Extract()
server, err := servers.Create(context.TODO(), client, createOpts, nil).Extract()
if err != nil {
panic(err)
}
Expand All @@ -159,7 +162,7 @@ server will use this volume as its root disk.
BlockDevice: blockDevices,
}
server, err := servers.Create(context.TODO(), client, createOpts).Extract()
server, err := servers.Create(context.TODO(), client, createOpts, nil).Extract()
if err != nil {
panic(err)
}
Expand All @@ -183,7 +186,7 @@ This example will create a server with an existing volume as its root disk.
BlockDevice: blockDevices,
}
server, err := servers.Create(context.TODO(), client, createOpts).Extract()
server, err := servers.Create(context.TODO(), client, createOpts, nil).Extract()
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -228,7 +231,7 @@ ephemeral disks must have an index of -1.
BlockDevice: blockDevices,
}
server, err := servers.Create(context.TODO(), client, createOpts).Extract()
server, err := servers.Create(context.TODO(), client, createOpts, nil).Extract()
if err != nil {
panic(err)
}
Expand Down
69 changes: 32 additions & 37 deletions openstack/compute/v2/servers/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"maps"
"net"
"regexp"
"strings"
Expand Down Expand Up @@ -128,14 +129,14 @@ func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pa
})
}

// SchedulerHintsCreateOptsBuilder builds the scheduler hints into a serializable format.
type SchedulerHintsCreateOptsBuilder interface {
ToServerSchedulerHintsCreateMap() (map[string]interface{}, error)
// SchedulerHintOptsBuilder builds the scheduler hints into a serializable format.
type SchedulerHintOptsBuilder interface {
ToSchedulerHintsMap() (map[string]interface{}, error)
}

// SchedulerHints represents a set of scheduling hints that are passed to the
// SchedulerHintOpts represents a set of scheduling hints that are passed to the
// OpenStack scheduler.
type SchedulerHints struct {
type SchedulerHintOpts struct {
// Group specifies a Server Group to place the instance in.
Group string

Expand Down Expand Up @@ -164,16 +165,16 @@ type SchedulerHints struct {
AdditionalProperties map[string]interface{}
}

// ToServerSchedulerHintsMap builds the scheduler hints into a serializable format.
func (opts SchedulerHints) ToServerSchedulerHintsCreateMap() (map[string]interface{}, error) {
// ToSchedulerHintsMap assembles a request body for scheduler hints.
func (opts SchedulerHintOpts) ToSchedulerHintsMap() (map[string]interface{}, error) {
sh := make(map[string]interface{})

uuidRegex, _ := regexp.Compile("^[a-z0-9]{8}-[a-z0-9]{4}-[1-5][a-z0-9]{3}-[a-z0-9]{4}-[a-z0-9]{12}$")

if opts.Group != "" {
if !uuidRegex.MatchString(opts.Group) {
err := gophercloud.ErrInvalidInput{}
err.Argument = "servers.SchedulerHints.Group"
err.Argument = "servers.schedulerhints.SchedulerHintOpts.Group"
err.Value = opts.Group
err.Info = "Group must be a UUID"
return nil, err
Expand All @@ -185,7 +186,7 @@ func (opts SchedulerHints) ToServerSchedulerHintsCreateMap() (map[string]interfa
for _, diffHost := range opts.DifferentHost {
if !uuidRegex.MatchString(diffHost) {
err := gophercloud.ErrInvalidInput{}
err.Argument = "servers.SchedulerHints.DifferentHost"
err.Argument = "servers.schedulerhints.SchedulerHintOpts.DifferentHost"
err.Value = opts.DifferentHost
err.Info = "The hosts must be in UUID format."
return nil, err
Expand All @@ -198,7 +199,7 @@ func (opts SchedulerHints) ToServerSchedulerHintsCreateMap() (map[string]interfa
for _, sameHost := range opts.SameHost {
if !uuidRegex.MatchString(sameHost) {
err := gophercloud.ErrInvalidInput{}
err.Argument = "servers.SchedulerHints.SameHost"
err.Argument = "servers.schedulerhints.SchedulerHintOpts.SameHost"
err.Value = opts.SameHost
err.Info = "The hosts must be in UUID format."
return nil, err
Expand All @@ -222,7 +223,7 @@ func (opts SchedulerHints) ToServerSchedulerHintsCreateMap() (map[string]interfa
if len(opts.Query) > 0 {
if len(opts.Query) < 3 {
err := gophercloud.ErrInvalidInput{}
err.Argument = "servers.SchedulerHints.Query"
err.Argument = "servers.schedulerhints.SchedulerHintOpts.Query"
err.Value = opts.Query
err.Info = "Must be a conditional statement in the format of [op,variable,value]"
return nil, err
Expand All @@ -232,7 +233,7 @@ func (opts SchedulerHints) ToServerSchedulerHintsCreateMap() (map[string]interfa
b, err := json.Marshal(opts.Query)
if err != nil {
err := gophercloud.ErrInvalidInput{}
err.Argument = "servers.SchedulerHints.Query"
err.Argument = "servers.schedulerhints.SchedulerHintOpts.Query"
err.Value = opts.Query
err.Info = "Must be a conditional statement in the format of [op,variable,value]"
return nil, err
Expand All @@ -252,7 +253,7 @@ func (opts SchedulerHints) ToServerSchedulerHintsCreateMap() (map[string]interfa
if opts.BuildNearHostIP != "" {
if _, _, err := net.ParseCIDR(opts.BuildNearHostIP); err != nil {
err := gophercloud.ErrInvalidInput{}
err.Argument = "servers.SchedulerHints.BuildNearHostIP"
err.Argument = "servers.schedulerhints.SchedulerHintOpts.BuildNearHostIP"
err.Value = opts.BuildNearHostIP
err.Info = "Must be a valid subnet in the form 192.168.1.1/24"
return nil, err
Expand All @@ -268,7 +269,11 @@ func (opts SchedulerHints) ToServerSchedulerHintsCreateMap() (map[string]interfa
}
}

return sh, nil
if len(sh) == 0 {
return sh, nil
}

return map[string]interface{}{"os:scheduler_hints": sh}, nil
}

// Network is used within CreateOpts to control a new server's network
Expand Down Expand Up @@ -503,9 +508,6 @@ type CreateOpts struct {

// DiskConfig [optional] controls how the created server's disk is partitioned.
DiskConfig DiskConfig `json:"OS-DCF:diskConfig,omitempty"`

// SchedulerHints provides a set of hints to the scheduler.
SchedulerHints SchedulerHintsCreateOptsBuilder
}

// ToServerCreateMap assembles a request body based on the contents of a
Expand All @@ -518,8 +520,6 @@ func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) {
return nil, err
}

delete(b, "SchedulerHints")

if opts.UserData != nil {
var userData string
if _, err := base64.StdEncoding.DecodeString(string(opts.UserData)); err != nil {
Expand Down Expand Up @@ -578,32 +578,27 @@ func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) {
// Now we do our enveloping
b = map[string]interface{}{"server": b}

if opts.SchedulerHints == nil {
return b, nil
}

schedulerHints, err := opts.SchedulerHints.ToServerSchedulerHintsCreateMap()
if err != nil {
return nil, err
}

if len(schedulerHints) == 0 {
return b, nil
}

b["os:scheduler_hints"] = schedulerHints

return b, nil
}

// Create requests a server to be provisioned to the user in the current tenant.
func Create(ctx context.Context, client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
reqBody, err := opts.ToServerCreateMap()
func Create(ctx context.Context, client *gophercloud.ServiceClient, opts CreateOptsBuilder, hintOpts SchedulerHintOptsBuilder) (r CreateResult) {
b, err := opts.ToServerCreateMap()
if err != nil {
r.Err = err
return
}
resp, err := client.Post(ctx, createURL(client), reqBody, &r.Body, &gophercloud.RequestOpts{

if hintOpts != nil {
sh, err := hintOpts.ToSchedulerHintsMap()
if err != nil {
r.Err = err
return
}
maps.Copy(b, sh)
}

resp, err := client.Post(ctx, createURL(client), b, &r.Body, &gophercloud.RequestOpts{
OkCodes: []int{200, 202},
})
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
Expand Down
2 changes: 0 additions & 2 deletions openstack/compute/v2/servers/testing/fixtures_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -721,8 +721,6 @@ func (opts CreateOptsWithCustomField) ToServerCreateMap() (map[string]interface{
return nil, err
}

delete(b, "SchedulerHints")

return map[string]interface{}{"server": b}, nil
}

Expand Down

0 comments on commit d520ff8

Please sign in to comment.