-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ability to handle partition match with the machine allocation constraint map response. #75
Add ability to handle partition match with the machine allocation constraint map response. #75
Conversation
…straint map response.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few initial thoughts before lunch - I'm not sure of the need to change the map values from int to interface{}/int/float64
blockdevice.go
Outdated
@@ -77,6 +89,14 @@ func (b *blockdevice) Size() uint64 { | |||
return b.size | |||
} | |||
|
|||
// FileSystem implements BlockDevice. | |||
func (b *blockdevice) FileSystem() FileSystem { | |||
if b.filesystem == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can just return b.filesystem here
no need for if {}
blockdevice.go
Outdated
"partitions": schema.List(schema.StringMap(schema.Any())), | ||
} | ||
checker := schema.FieldMap(fields, nil) | ||
defaults := schema.Defaults{ | ||
"uuid": "", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you even need to specify a default given that above you have:
"uuid": schema.OneOf(schema.Nil(""), schema.String()),
eg model and id_path are processed the same was as uuid and don't need a default to be set
blockdevice.go
Outdated
@@ -157,17 +182,26 @@ func blockdevice_2_0(source map[string]interface{}) (*blockdevice, error) { | |||
// From here we know that the map returned from the schema coercion | |||
// contains fields of the right type. | |||
|
|||
var filesystem *filesystem | |||
if fsSource := valid["filesystem"]; fsSource != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be better:
if fsSource, ok := valid["filesystem"].(map[string]interface{}); ok {
filesystem, err = filesystem2_0(fsSource)
@@ -41,6 +42,11 @@ func (*blockdeviceSuite) TestReadBlockDevices(c *gc.C) { | |||
partition := partitions[0] | |||
c.Check(partition.ID(), gc.Equals, 1) | |||
c.Check(partition.UsedFor(), gc.Equals, "ext4 formatted filesystem mounted at /") | |||
|
|||
fs := blockdevice.FileSystem() | |||
c.Assert(fs, gc.NotNil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a check for the actual content
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Type()
and MountPoint()
are checked below? Is there something different your looking for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, what's below does the job
@@ -89,7 +95,13 @@ var blockdevicesResponse = ` | |||
"size": 8581545984 | |||
} | |||
], | |||
"filesystem": null, | |||
"filesystem": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should retain this "WithNulls" test and add a new one without
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This diff is confusing I still have the filesystem is nil in the WithNulls. I added another check to ensure that filesystem stays nil in the WithNulls.
controller.go
Outdated
} | ||
|
||
if interfaceMatches, found := constraintsMap["interfaces"]; found { | ||
matches := convertConstraintMatches(interfaceMatches) | ||
for label, ids := range matches { | ||
interfaces := make([]Interface, len(ids)) | ||
for index, id := range ids { | ||
iface := machine.Interface(id) | ||
iface := machine.Interface(id.(int)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is dangerous given the change above to schema.Any() as it could panic
Why was the change to schema.Any() needed?
controller.go
Outdated
return empty, NewDeserializationError("constraint match storage %q: %d does not match a block device for the machine", label, id) | ||
storageDevices := make([]StorageDevice, len(ids)) | ||
for index, storageId := range ids { | ||
if id, ok := storageId.(float64); ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Be very careful about type asserts like this as they will panic if the value is the wrong type.
We had int previously and now flot64 here. It seems like you are catering for a json marshall/unmarshal use case?
Maybe you want to use a cast float64(storageId)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I now understand that if we have a number it's a block device and a string is a partition. Can we add a comment to explain this concept.
blockdevice.go
Outdated
"partitions": schema.List(schema.StringMap(schema.Any())), | ||
} | ||
checker := schema.FieldMap(fields, nil) | ||
defaults := schema.Defaults{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can just revert to the previous code here
controller.go
Outdated
@@ -931,15 +932,15 @@ func parseAllocateConstraintsResponse(source interface{}, machine *machine) (Con | |||
constraintsMap := valid["constraints_by_type"].(map[string]interface{}) | |||
result := ConstraintMatches{ | |||
Interfaces: make(map[string][]Interface), | |||
Storage: make(map[string][]BlockDevice), | |||
Storage: make(map[string][]StorageDevice), | |||
} | |||
|
|||
if interfaceMatches, found := constraintsMap["interfaces"]; found { | |||
matches := convertConstraintMatches(interfaceMatches) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we are processing the "interfaces" map here.
The "interfaces" schema defines a map of string-> int list.
We should have a version of convertConstraintMatches() which returns the correct type so we don't need to use id.(int)
controller.go
Outdated
} else if id, ok := storageId.(string); ok { | ||
// Should link to a partition. | ||
const partPrefix = "partition:" | ||
if strings.HasPrefix(id, partPrefix) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To save indentation, do the check for the expected prefix and exit.
Then the rest of the stuff can be done without indenting
controller.go
Outdated
} | ||
} | ||
return result, nil | ||
} | ||
|
||
func convertConstraintMatches(source interface{}) map[string][]int { | ||
func convertConstraintMatches(source interface{}) map[string][]interface{} { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As stated above, maybe 2 versions of this to return the expected typed map and error if the values don't conform
interfaces.go
Outdated
@@ -234,6 +234,9 @@ type Machine interface { | |||
// BlockDevice returns the block device for the machine that matches the | |||
// id specified. If there is no match, nil is returned. | |||
BlockDevice(id int) BlockDevice | |||
// Partition returns the partition for the machine that matches the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit pic - blank line before comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good, main issue is tweaking how the data is parsed to better handle the different type values
Thanks for the review. I have updated the branch to cleanup the areas you called out. The Any and the |
|
!!build!! |
2 similar comments
!!build!! |
!!build!! |
|
MAAS 2.5 has added the ability for tags to match a partition and not just a block device when performing allocation with storage constraints.
This change allows this to on MAAS 2.5, while also not breaking versions before. This adds a new interface
StorageDevice
that can be either a partition or a block device.