Skip to content

Commit 187c807

Browse files
EmilienMmandre
andcommitted
Add ephemeral storage support to the AdditionalBlockDevices
Co-authored-by: Emilien Macchi <[email protected]> Co-authored-by: Martin André <[email protected]>
1 parent f28da18 commit 187c807

14 files changed

+577
-121
lines changed

api/v1alpha7/openstackmachine_types.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,15 @@ type OpenStackMachineSpec struct {
8484
// The volume metadata to boot from
8585
RootVolume *RootVolume `json:"rootVolume,omitempty"`
8686

87-
// AdditionalBlockDevices is a list of specifications for additional block devices to attach to the server instance
87+
// additionalBlockDevices is a list of specifications for additional block devices to attach to the server instance
88+
//
89+
// + ---
90+
// + While it's possible to have unlimited number of block devices attached to a server instance, the number is
91+
// + limited to 255 to avoid rule cost exceeded error in CRD validation.
92+
// +kubebuilder:validation:MaxItems=255
8893
// +listType=map
8994
// +listMapKey=name
95+
// +optional
9096
AdditionalBlockDevices []AdditionalBlockDevice `json:"additionalBlockDevices,omitempty"`
9197

9298
// The server group to assign the machine to

api/v1alpha7/openstackmachine_webhook.go

+8
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ func (r *OpenStackMachine) ValidateCreate() (admission.Warnings, error) {
6262
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "identityRef", "kind"), "must be a Secret"))
6363
}
6464

65+
if r.Spec.RootVolume != nil && r.Spec.AdditionalBlockDevices != nil {
66+
for _, device := range r.Spec.AdditionalBlockDevices {
67+
if device.Name == "root" {
68+
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "additionalBlockDevices"), "cannot contain a device named \"root\" when rootVolume is set"))
69+
}
70+
}
71+
}
72+
6573
return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs)
6674
}
6775

api/v1alpha7/types.go

+73-10
Original file line numberDiff line numberDiff line change
@@ -163,20 +163,83 @@ type RootVolume struct {
163163
AvailabilityZone string `json:"availabilityZone,omitempty"`
164164
}
165165

166-
type AdditionalBlockDevice struct {
167-
// Name of the Cinder volume in the context of a machine.
168-
// It will be combined with the machine name to make the actual volume name.
169-
Name string `json:"name"`
170-
// Size is the size in GB of the volume.
171-
Size int `json:"diskSize"`
172-
// VolumeType is the volume type of the volume.
173-
// If omitted, the default type will be used.
174-
VolumeType string `json:"volumeType,omitempty"`
175-
// AvailabilityZone is the volume availability zone to create the volume in.
166+
// blockDeviceStorage is the storage type of a block device to create and
167+
// contains additional storage options.
168+
// +kubebuilder:validation:XValidation:rule="self.type == 'Volume' || !has(self.volume)",message="volume is forbidden when type is not Volume"
169+
// +union
170+
//
171+
//nolint:godot
172+
type BlockDeviceStorage struct {
173+
// type is the type of block device to create.
174+
// This can be either "Volume" or "Local".
175+
// +kubebuilder:validation:Enum="Volume";"Local"
176+
// +kubebuilder:validation:Required
177+
// +unionDiscriminator
178+
Type BlockDeviceType `json:"type"`
179+
180+
// volume contains additional storage options for a volume block device.
181+
// +optional
182+
// +unionMember,optional
183+
Volume *BlockDeviceVolume `json:"volume,omitempty"`
184+
}
185+
186+
// blockDeviceVolume contains additional storage options for a volume block device.
187+
type BlockDeviceVolume struct {
188+
// type is the Cinder volume type of the volume.
189+
// If omitted, the default Cinder volume type that is configured in the OpenStack cloud
190+
// will be used.
191+
// The maximum length of a volume type name is 255 characters, as per the OpenStack limit.
192+
// +kubebuilder:validation:MinLength=1
193+
// +kubebuilder:validation:MaxLength=255
194+
// +optional
195+
Type string `json:"type,omitempty"`
196+
197+
// availabilityZone is the volume availability zone to create the volume in.
176198
// If omitted, the availability zone of the server will be used.
199+
// The availability zone must NOT contain spaces otherwise it will lead to volume that belongs
200+
// to this availability zone register failure, see kubernetes/cloud-provider-openstack#1379 for
201+
// further information.
202+
// The maximum length of availability zone name is 63 as per labels limits.
203+
// +kubebuilder:validation:MinLength=1
204+
// +kubebuilder:validation:MaxLength=63
205+
// +kubebuilder:validation:XValidation:rule="!self.contains(' ')",message="availabilityZone may not contain spaces"
206+
// +optional
177207
AvailabilityZone string `json:"availabilityZone,omitempty"`
178208
}
179209

210+
// additionalBlockDevice is a block device to attach to the server.
211+
type AdditionalBlockDevice struct {
212+
// name of the block device in the context of a machine.
213+
// If the block device is a volume, the Cinder volume will be named
214+
// as a combination of the machine name and this name.
215+
// Also, this name will be used for tagging the block device.
216+
// Information about the block device tag can be obtained from the OpenStack
217+
// metadata API or the config drive.
218+
// +kubebuilder:validation:Required
219+
Name string `json:"name"`
220+
221+
// sizeGiB is the size of the block device in gibibytes (GiB).
222+
// +kubebuilder:validation:Minimum=1
223+
// +kubebuilder:validation:Required
224+
SizeGiB int `json:"sizeGiB"`
225+
226+
// storage specifies the storage type of the block device and
227+
// additional storage options.
228+
// +kubebuilder:validation:Required
229+
Storage BlockDeviceStorage `json:"storage"`
230+
}
231+
232+
// BlockDeviceType defines the type of block device to create.
233+
type BlockDeviceType string
234+
235+
const (
236+
// LocalBlockDevice is an ephemeral block device attached to the server.
237+
LocalBlockDevice BlockDeviceType = "Local"
238+
239+
// VolumeBlockDevice is a volume block device attached to the server.
240+
VolumeBlockDevice BlockDeviceType = "Volume"
241+
)
242+
180243
// NetworkStatus contains basic information about an existing neutron network.
181244
type NetworkStatus struct {
182245
Name string `json:"name"`

api/v1alpha7/zz_generated.deepcopy.go

+39-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml

+68-17
Original file line numberDiff line numberDiff line change
@@ -3771,31 +3771,82 @@ spec:
37713771
description: Instance for the bastion itself
37723772
properties:
37733773
additionalBlockDevices:
3774-
description: AdditionalBlockDevices is a list of specifications
3774+
description: additionalBlockDevices is a list of specifications
37753775
for additional block devices to attach to the server instance
37763776
items:
3777+
description: additionalBlockDevice is a block device to
3778+
attach to the server.
37773779
properties:
3778-
availabilityZone:
3779-
description: AvailabilityZone is the volume availability
3780-
zone to create the volume in. If omitted, the availability
3781-
zone of the server will be used.
3782-
type: string
3783-
diskSize:
3784-
description: Size is the size in GB of the volume.
3785-
type: integer
37863780
name:
3787-
description: Name of the Cinder volume in the context
3788-
of a machine. It will be combined with the machine
3789-
name to make the actual volume name.
3790-
type: string
3791-
volumeType:
3792-
description: VolumeType is the volume type of the volume.
3793-
If omitted, the default type will be used.
3781+
description: name of the block device in the context
3782+
of a machine. If the block device is a volume, the
3783+
Cinder volume will be named as a combination of the
3784+
machine name and this name. Also, this name will be
3785+
used for tagging the block device. Information about
3786+
the block device tag can be obtained from the OpenStack
3787+
metadata API or the config drive.
37943788
type: string
3789+
sizeGiB:
3790+
description: sizeGiB is the size of the block device
3791+
in gibibytes (GiB).
3792+
minimum: 1
3793+
type: integer
3794+
storage:
3795+
description: storage specifies the storage type of the
3796+
block device and additional storage options.
3797+
properties:
3798+
type:
3799+
description: type is the type of block device to
3800+
create. This can be either "Volume" or "Local".
3801+
enum:
3802+
- Volume
3803+
- Local
3804+
type: string
3805+
volume:
3806+
description: volume contains additional storage
3807+
options for a volume block device.
3808+
properties:
3809+
availabilityZone:
3810+
description: availabilityZone is the volume
3811+
availability zone to create the volume in.
3812+
If omitted, the availability zone of the server
3813+
will be used. The availability zone must NOT
3814+
contain spaces otherwise it will lead to volume
3815+
that belongs to this availability zone register
3816+
failure, see kubernetes/cloud-provider-openstack#1379
3817+
for further information. The maximum length
3818+
of availability zone name is 63 as per labels
3819+
limits.
3820+
maxLength: 63
3821+
minLength: 1
3822+
type: string
3823+
x-kubernetes-validations:
3824+
- message: availabilityZone may not contain
3825+
spaces
3826+
rule: '!self.contains('' '')'
3827+
type:
3828+
description: type is the Cinder volume type
3829+
of the volume. If omitted, the default Cinder
3830+
volume type that is configured in the OpenStack
3831+
cloud will be used. The maximum length of
3832+
a volume type name is 255 characters, as per
3833+
the OpenStack limit.
3834+
maxLength: 255
3835+
minLength: 1
3836+
type: string
3837+
type: object
3838+
required:
3839+
- type
3840+
type: object
3841+
x-kubernetes-validations:
3842+
- message: volume is forbidden when type is not Volume
3843+
rule: self.type == 'Volume' || !has(self.volume)
37953844
required:
3796-
- diskSize
37973845
- name
3846+
- sizeGiB
3847+
- storage
37983848
type: object
3849+
maxItems: 255
37993850
type: array
38003851
x-kubernetes-list-map-keys:
38013852
- name

0 commit comments

Comments
 (0)