Skip to content

Commit

Permalink
WIP - Add ephemeral storage support to the AdditionalBlockDevices
Browse files Browse the repository at this point in the history
Fixes: #1692
  • Loading branch information
EmilienM committed Sep 30, 2023
1 parent dda7454 commit ef93718
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 41 deletions.
21 changes: 18 additions & 3 deletions api/v1alpha7/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,18 +164,33 @@ type RootVolume struct {
}

type AdditionalBlockDevice struct {
// BlockDeviceType is the type of block device to create.
// This can be either "volume" or "local".
// +kubebuilder:validation:Required
// +kubebuilder:validation:Enum=volume;local
BlockDeviceType string `json:"blockDeviceType"`

// Here I'm hesitant to add GuestFormat. Not to let users choose the format of the block device
// (ie ext4, etc) because I think this should be handled by the user when the instane is started,
// but rather to let the user create swap partitions.
// I see 3 options:
// 1. Add GuestFormat here and let the user create swap partitions, among other filesystems (ext4, etc)
// 2. Add a new field for swap partitions
// 3. Don't add fields, the block device will be blank and can't be used for swap partitions.

// NameSuffix is the suffix to be added to volume names.
// It will be combined with the machine name to make the volume name.
NameSuffix string `json:"nameSuffix"`
// Size is the size in GB of the volume.
// Required if SourceType is "volume"
NameSuffix string `json:"nameSuffix,omitempty"`
// Size is the size in GB of the block device.
Size int `json:"diskSize"`
// VolumeType is the volume type of the volume.
// If omitted, the default type will be used.
VolumeType string `json:"volumeType,omitempty"`
// AvailabilityZone is the volume availability zone to create the volume in.
// If omitted, the availability zone of the server will be used.
AvailabilityZone string `json:"availabilityZone,omitempty"`
// Tag is a tag to add to the volume attachment.
// Tag is a tag to add to the block device attachment.
// This is then available in the instance metadata, allowing devices to be
// identified by tag inside the server.
Tag string `json:"tag,omitempty"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3780,26 +3780,35 @@ spec:
zone to create the volume in. If omitted, the availability
zone of the server will be used.
type: string
blockDeviceType:
description: BlockDeviceType is the type of block device
to create. This can be either "volume" or "local".
enum:
- volume
- local
type: string
diskSize:
description: Size is the size in GB of the volume.
description: Size is the size in GB of the block device.
type: integer
nameSuffix:
description: NameSuffix is the suffix to be added to
volume names. It will be combined with the machine
name to make the volume name.
name to make the volume name. Required if SourceType
is "volume"
type: string
tag:
description: Tag is a tag to add to the volume attachment.
This is then available in the instance metadata, allowing
devices to be identified by tag inside the server.
description: Tag is a tag to add to the block device
attachment. This is then available in the instance
metadata, allowing devices to be identified by tag
inside the server.
type: string
volumeType:
description: VolumeType is the volume type of the volume.
If omitted, the default type will be used.
type: string
required:
- blockDeviceType
- diskSize
- nameSuffix
type: object
type: array
cloudName:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1622,28 +1622,38 @@ spec:
If omitted, the availability zone of the server
will be used.
type: string
blockDeviceType:
description: BlockDeviceType is the type of
block device to create. This can be either
"volume" or "local".
enum:
- volume
- local
type: string
diskSize:
description: Size is the size in GB of the volume.
description: Size is the size in GB of the block
device.
type: integer
nameSuffix:
description: NameSuffix is the suffix to be
added to volume names. It will be combined
with the machine name to make the volume name.
Required if SourceType is "volume"
type: string
tag:
description: Tag is a tag to add to the volume
attachment. This is then available in the
instance metadata, allowing devices to be
identified by tag inside the server.
description: Tag is a tag to add to the block
device attachment. This is then available
in the instance metadata, allowing devices
to be identified by tag inside the server.
type: string
volumeType:
description: VolumeType is the volume type of
the volume. If omitted, the default type will
be used.
type: string
required:
- blockDeviceType
- diskSize
- nameSuffix
type: object
type: array
cloudName:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1169,26 +1169,33 @@ spec:
to create the volume in. If omitted, the availability zone
of the server will be used.
type: string
blockDeviceType:
description: BlockDeviceType is the type of block device to
create. This can be either "volume" or "local".
enum:
- volume
- local
type: string
diskSize:
description: Size is the size in GB of the volume.
description: Size is the size in GB of the block device.
type: integer
nameSuffix:
description: NameSuffix is the suffix to be added to volume
names. It will be combined with the machine name to make the
volume name.
volume name. Required if SourceType is "volume"
type: string
tag:
description: Tag is a tag to add to the volume attachment. This
is then available in the instance metadata, allowing devices
to be identified by tag inside the server.
description: Tag is a tag to add to the block device attachment.
This is then available in the instance metadata, allowing
devices to be identified by tag inside the server.
type: string
volumeType:
description: VolumeType is the volume type of the volume. If
omitted, the default type will be used.
type: string
required:
- blockDeviceType
- diskSize
- nameSuffix
type: object
type: array
cloudName:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -968,26 +968,35 @@ spec:
zone to create the volume in. If omitted, the availability
zone of the server will be used.
type: string
blockDeviceType:
description: BlockDeviceType is the type of block device
to create. This can be either "volume" or "local".
enum:
- volume
- local
type: string
diskSize:
description: Size is the size in GB of the volume.
description: Size is the size in GB of the block device.
type: integer
nameSuffix:
description: NameSuffix is the suffix to be added to
volume names. It will be combined with the machine
name to make the volume name.
name to make the volume name. Required if SourceType
is "volume"
type: string
tag:
description: Tag is a tag to add to the volume attachment.
This is then available in the instance metadata, allowing
devices to be identified by tag inside the server.
description: Tag is a tag to add to the block device
attachment. This is then available in the instance
metadata, allowing devices to be identified by tag
inside the server.
type: string
volumeType:
description: VolumeType is the volume type of the volume.
If omitted, the default type will be used.
type: string
required:
- blockDeviceType
- diskSize
- nameSuffix
type: object
type: array
cloudName:
Expand Down
30 changes: 24 additions & 6 deletions pkg/cloud/services/compute/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ func (s *Service) getBlockDevices(eventObject runtime.Object, instanceSpec *Inst

if hasRootVolume(instanceSpec) {
rootVolumeToBlockDevice := infrav1.AdditionalBlockDevice{
BlockDeviceType: "volume",
NameSuffix: "root",
AvailabilityZone: instanceSpec.RootVolume.AvailabilityZone,
Size: instanceSpec.RootVolume.Size,
Expand Down Expand Up @@ -488,16 +489,33 @@ func (s *Service) getBlockDevices(eventObject runtime.Object, instanceSpec *Inst
}

for _, blockDeviceSpec := range instanceSpec.AdditionalBlockDevices {
blockDevice, err := s.getOrCreateVolumeBuilder(eventObject, instanceSpec, blockDeviceSpec, "", fmt.Sprintf("Additional block device for %s", instanceSpec.Name))
if err != nil {
return []bootfromvolume.BlockDevice{}, err
var bdUUID string
var sourceType bootfromvolume.SourceType
var destinationType bootfromvolume.DestinationType
var bdSize int
if blockDeviceSpec.BlockDeviceType == "volume" {
blockDevice, err := s.getOrCreateVolumeBuilder(eventObject, instanceSpec, blockDeviceSpec, "", fmt.Sprintf("Additional block device for %s", instanceSpec.Name))
if err != nil {
return []bootfromvolume.BlockDevice{}, err
}
bdUUID = blockDevice.ID
sourceType = bootfromvolume.SourceVolume
destinationType = bootfromvolume.DestinationVolume
} else if blockDeviceSpec.BlockDeviceType == "local" {
sourceType = bootfromvolume.SourceBlank
destinationType = bootfromvolume.DestinationLocal
bdSize = blockDeviceSpec.Size
} else {
return []bootfromvolume.BlockDevice{}, fmt.Errorf("invalid block device type %s", blockDeviceSpec.BlockDeviceType)
}

blockDevices = append(blockDevices, bootfromvolume.BlockDevice{
SourceType: bootfromvolume.SourceVolume,
DestinationType: bootfromvolume.DestinationVolume,
UUID: blockDevice.ID,
SourceType: sourceType,
DestinationType: destinationType,
UUID: bdUUID,
BootIndex: -1,
DeleteOnTermination: true,
VolumeSize: bdSize,
Tag: blockDeviceSpec.Tag,
})
}
Expand Down
32 changes: 24 additions & 8 deletions pkg/cloud/services/compute/instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -658,10 +658,16 @@ func TestService_ReconcileInstance(t *testing.T) {
}
s.AdditionalBlockDevices = []infrav1.AdditionalBlockDevice{
{
NameSuffix: "disk1",
Size: 50,
VolumeType: "test-volume-type",
Tag: "etcd",
BlockDeviceType: "volume",
NameSuffix: "disk1",
Size: 50,
VolumeType: "test-volume-type",
Tag: "etcd",
},
{
BlockDeviceType: "local",
Size: 10,
Tag: "db",
},
}
return s
Expand Down Expand Up @@ -713,6 +719,14 @@ func TestService_ReconcileInstance(t *testing.T) {
"destination_type": "volume",
"tag": "etcd",
},
{
"source_type": "blank",
"destination_type": "local",
"boot_index": float64(-1),
"delete_on_termination": true,
"volume_size": float64(10),
"tag": "db",
},
}
expectCreateServer(r.compute, createMap, false)
expectServerPollSuccess(r.compute)
Expand All @@ -727,10 +741,11 @@ func TestService_ReconcileInstance(t *testing.T) {
s := getDefaultInstanceSpec()
s.AdditionalBlockDevices = []infrav1.AdditionalBlockDevice{
{
NameSuffix: "disk1",
Size: 50,
VolumeType: "test-volume-type",
Tag: "etcd",
BlockDeviceType: "volume",
NameSuffix: "disk1",
Size: 50,
VolumeType: "test-volume-type",
Tag: "etcd",
},
}
return s
Expand Down Expand Up @@ -783,6 +798,7 @@ func TestService_ReconcileInstance(t *testing.T) {
s := getDefaultInstanceSpec()
s.AdditionalBlockDevices = []infrav1.AdditionalBlockDevice{
{
BlockDeviceType: "volume",
NameSuffix: "disk1",
Size: 50,
VolumeType: "test-volume-type",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@
path: /spec/template/spec/additionalBlockDevices
value:
- diskSize: 1
blockDeviceType: volume
nameSuffix: extravol
tag: extravol
- diskSize: 1
blockDeviceType: local
tag: etcd
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
path: /spec/template/spec/additionalBlockDevices
value:
- diskSize: 1
blockDeviceType: volume
nameSuffix: extravol
volumeType: ${OPENSTACK_VOLUME_TYPE_ALT}
availabilityZone: ${OPENSTACK_FAILURE_DOMAIN}
tag: extravol
- diskSize: 1
blockDeviceType: local
tag: etcd

0 comments on commit ef93718

Please sign in to comment.