Skip to content

Commit

Permalink
baremetal: copy the implementation of rootdevicehints from baremetal-…
Browse files Browse the repository at this point in the history
…operator

Copy the struct and conversion function from the baremetal-operator
repository to avoid depending on that code directly in the installer's
API.

Signed-off-by: Doug Hellmann <dhellmann@redhat.com>
  • Loading branch information
dhellmann committed Aug 3, 2020
1 parent d75bf7a commit 6c70770
Show file tree
Hide file tree
Showing 4 changed files with 261 additions and 10 deletions.
3 changes: 1 addition & 2 deletions pkg/tfvars/baremetal/baremetal.go
Expand Up @@ -11,7 +11,6 @@ import (

"github.com/metal3-io/baremetal-operator/pkg/bmc"
"github.com/metal3-io/baremetal-operator/pkg/hardware"
"github.com/metal3-io/baremetal-operator/pkg/provisioner/ironic/devicehints"
"github.com/openshift/installer/pkg/tfvars/internal/cache"
"github.com/openshift/installer/pkg/types/baremetal"
"github.com/pkg/errors"
Expand Down Expand Up @@ -98,7 +97,7 @@ func TFVars(libvirtURI, bootstrapProvisioningIP, bootstrapOSImage, externalBridg

// host.RootDeviceHints overrides the root device hint in the profile
if host.RootDeviceHints != nil {
rootDeviceStringMap := devicehints.MakeHintMap(host.RootDeviceHints)
rootDeviceStringMap := host.RootDeviceHints.MakeHintMap()
for key, value := range rootDeviceStringMap {
rootDevice[key] = value
}
Expand Down
15 changes: 7 additions & 8 deletions pkg/types/baremetal/platform.go
@@ -1,7 +1,6 @@
package baremetal

import (
"github.com/metal3-io/baremetal-operator/pkg/apis/metal3/v1alpha1"
"github.com/openshift/installer/pkg/ipnet"
)

Expand All @@ -26,13 +25,13 @@ const (

// Host stores all the configuration data for a baremetal host.
type Host struct {
Name string `json:"name,omitempty" validate:"required,uniqueField"`
BMC BMC `json:"bmc"`
Role string `json:"role"`
BootMACAddress string `json:"bootMACAddress" validate:"required,uniqueField"`
HardwareProfile string `json:"hardwareProfile"`
RootDeviceHints *v1alpha1.RootDeviceHints `json:"rootDeviceHints,omitempty"`
BootMode BootMode `json:"bootMode,omitempty"`
Name string `json:"name,omitempty" validate:"required,uniqueField"`
BMC BMC `json:"bmc"`
Role string `json:"role"`
BootMACAddress string `json:"bootMACAddress" validate:"required,uniqueField"`
HardwareProfile string `json:"hardwareProfile"`
RootDeviceHints *RootDeviceHints `json:"rootDeviceHints,omitempty"`
BootMode BootMode `json:"bootMode,omitempty"`
}

// Platform stores all the global configuration that all machinesets use.
Expand Down
98 changes: 98 additions & 0 deletions pkg/types/baremetal/rootdevice.go
@@ -0,0 +1,98 @@
package baremetal

// This package replicates the code from
// https://github.com/metal3-io/baremetal-operator/pkg/provisioner/ironic/devicehints

import (
"fmt"
)

// RootDeviceHints holds the hints for specifying the storage location
// for the root filesystem for the image.
type RootDeviceHints struct {
// A Linux device name like "/dev/vda". The hint must match the
// actual value exactly.
DeviceName string `json:"deviceName,omitempty"`

// A SCSI bus address like 0:0:0:0. The hint must match the actual
// value exactly.
HCTL string `json:"hctl,omitempty"`

// A vendor-specific device identifier. The hint can be a
// substring of the actual value.
Model string `json:"model,omitempty"`

// The name of the vendor or manufacturer of the device. The hint
// can be a substring of the actual value.
Vendor string `json:"vendor,omitempty"`

// Device serial number. The hint must match the actual value
// exactly.
SerialNumber string `json:"serialNumber,omitempty"`

// The minimum size of the device in Gigabytes.
// +kubebuilder:validation:Minimum=0
MinSizeGigabytes int `json:"minSizeGigabytes,omitempty"`

// Unique storage identifier. The hint must match the actual value
// exactly.
WWN string `json:"wwn,omitempty"`

// Unique storage identifier with the vendor extension
// appended. The hint must match the actual value exactly.
WWNWithExtension string `json:"wwnWithExtension,omitempty"`

// Unique vendor storage identifier. The hint must match the
// actual value exactly.
WWNVendorExtension string `json:"wwnVendorExtension,omitempty"`

// True if the device should use spinning media, false otherwise.
Rotational *bool `json:"rotational,omitempty"`
}

// MakeHintMap converts a RootDeviceHints instance into a string map
// suitable to pass to ironic.
func (source *RootDeviceHints) MakeHintMap() map[string]string {
hints := map[string]string{}

if source == nil {
return hints
}

if source.DeviceName != "" {
hints["name"] = fmt.Sprintf("s== %s", source.DeviceName)
}
if source.HCTL != "" {
hints["hctl"] = fmt.Sprintf("s== %s", source.HCTL)
}
if source.Model != "" {
hints["model"] = fmt.Sprintf("<in> %s", source.Model)
}
if source.Vendor != "" {
hints["vendor"] = fmt.Sprintf("<in> %s", source.Vendor)
}
if source.SerialNumber != "" {
hints["serial"] = fmt.Sprintf("s== %s", source.SerialNumber)
}
if source.MinSizeGigabytes != 0 {
hints["size"] = fmt.Sprintf(">= %d", source.MinSizeGigabytes)
}
if source.WWN != "" {
hints["wwn"] = fmt.Sprintf("s== %s", source.WWN)
}
if source.WWNWithExtension != "" {
hints["wwn_with_extension"] = fmt.Sprintf("s== %s", source.WWNWithExtension)
}
if source.WWNVendorExtension != "" {
hints["wwn_vendor_extension"] = fmt.Sprintf("s== %s", source.WWNVendorExtension)
}
switch {
case source.Rotational == nil:
case *source.Rotational == true:
hints["rotational"] = "true"
case *source.Rotational == false:
hints["rotational"] = "false"
}

return hints
}
155 changes: 155 additions & 0 deletions pkg/types/baremetal/rootdevice_test.go
@@ -0,0 +1,155 @@
package baremetal

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestMakeHintMap(t *testing.T) {
addressableTrue := true
addressableFalse := false

for _, tc := range []struct {
Scenario string
Hints RootDeviceHints
Expected map[string]string
}{
{
Scenario: "device-name",
Hints: RootDeviceHints{
DeviceName: "userd_devicename",
},
Expected: map[string]string{
"name": "s== userd_devicename",
},
},
{
Scenario: "hctl",
Hints: RootDeviceHints{
HCTL: "1:2:3:4",
},
Expected: map[string]string{
"hctl": "s== 1:2:3:4",
},
},
{
Scenario: "model",
Hints: RootDeviceHints{
Model: "userd_model",
},
Expected: map[string]string{
"model": "<in> userd_model",
},
},
{
Scenario: "vendor",
Hints: RootDeviceHints{
Vendor: "userd_vendor",
},
Expected: map[string]string{
"vendor": "<in> userd_vendor",
},
},
{
Scenario: "serial-number",
Hints: RootDeviceHints{
SerialNumber: "userd_serial",
},
Expected: map[string]string{
"serial": "s== userd_serial",
},
},
{
Scenario: "min-size",
Hints: RootDeviceHints{
MinSizeGigabytes: 40,
},
Expected: map[string]string{
"size": ">= 40",
},
},
{
Scenario: "wwn",
Hints: RootDeviceHints{
WWN: "userd_wwn",
},
Expected: map[string]string{
"wwn": "s== userd_wwn",
},
},
{
Scenario: "wwn-with-extension",
Hints: RootDeviceHints{
WWNWithExtension: "userd_with_extension",
},
Expected: map[string]string{
"wwn_with_extension": "s== userd_with_extension",
},
},
{
Scenario: "wwn-extension",
Hints: RootDeviceHints{
WWNVendorExtension: "userd_vendor_extension",
},
Expected: map[string]string{
"wwn_vendor_extension": "s== userd_vendor_extension",
},
},
{
Scenario: "rotational-true",
Hints: RootDeviceHints{
Rotational: &addressableTrue,
},
Expected: map[string]string{
"rotational": "true",
},
},
{
Scenario: "rotational-false",
Hints: RootDeviceHints{
Rotational: &addressableFalse,
},
Expected: map[string]string{
"rotational": "false",
},
},
{
Scenario: "everything-bagel",
Hints: RootDeviceHints{
DeviceName: "userd_devicename",
HCTL: "1:2:3:4",
Model: "userd_model",
Vendor: "userd_vendor",
SerialNumber: "userd_serial",
MinSizeGigabytes: 40,
WWN: "userd_wwn",
WWNWithExtension: "userd_with_extension",
WWNVendorExtension: "userd_vendor_extension",
Rotational: &addressableTrue,
},
Expected: map[string]string{
"name": "s== userd_devicename",
"hctl": "s== 1:2:3:4",
"model": "<in> userd_model",
"vendor": "<in> userd_vendor",
"serial": "s== userd_serial",
"size": ">= 40",
"wwn": "s== userd_wwn",
"wwn_with_extension": "s== userd_with_extension",
"wwn_vendor_extension": "s== userd_vendor_extension",
"rotational": "true",
},
},
{
Scenario: "empty",
Hints: RootDeviceHints{},
Expected: map[string]string{},
},
} {
t.Run(tc.Scenario, func(t *testing.T) {
actual := tc.Hints.MakeHintMap()
assert.Equal(t, tc.Expected, actual, "hint map does not match")
})
}
}

0 comments on commit 6c70770

Please sign in to comment.