Skip to content

Commit

Permalink
Ephemeral machine volumes
Browse files Browse the repository at this point in the history
This change introduces the ability for machines to request ephemeral
volumes. Additionally, the ephemeral handling for machine sub-objects
(i.e. currently `NetworkInterface` and `Volume`) has been improved to
include status fields informing about the binding phase.
  • Loading branch information
adracus committed Jun 2, 2022
1 parent 6a13753 commit b7693b7
Show file tree
Hide file tree
Showing 38 changed files with 1,233 additions and 211 deletions.
8 changes: 8 additions & 0 deletions apis/compute/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package compute

import (
"github.com/onmetal/onmetal-api/apis/networking"
"github.com/onmetal/onmetal-api/apis/storage"
)

// EphemeralNetworkInterfaceSource is a definition for an ephemeral (i.e. coupled to the lifetime of the surrounding
Expand All @@ -24,3 +25,10 @@ type EphemeralNetworkInterfaceSource struct {
// NetworkInterfaceTemplate is the template definition of the networking.NetworkInterface.
NetworkInterfaceTemplate *networking.NetworkInterfaceTemplateSpec
}

// EphemeralVolumeSource is a definition for an ephemeral (i.e. coupled to the lifetime of the surrounding object)
// storage.Volume.
type EphemeralVolumeSource struct {
// VolumeTemplate is the template definition of the storage.Volume.
VolumeTemplate *storage.VolumeTemplateSpec
}
27 changes: 27 additions & 0 deletions apis/compute/machine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ type VolumeSource struct {
VolumeRef *corev1.LocalObjectReference
// EmptyDisk instructs to use a Volume offered by the machine pool provider.
EmptyDisk *EmptyDiskVolumeSource
// Ephemeral instructs to create an ephemeral (i.e. coupled to the lifetime of the surrounding object)
// Volume to use.
Ephemeral *EphemeralVolumeSource
}

// EmptyDiskVolumeSource is a volume that's offered by the machine pool provider.
Expand All @@ -109,20 +112,44 @@ type EmptyDiskVolumeSource struct {
type NetworkInterfaceStatus struct {
// Name is the name of the NetworkInterface to whom the status belongs to.
Name string
// Phase is the NetworkInterface binding phase of the NetworkInterface.
Phase NetworkInterfacePhase
// IPs are the ips allocated for the network interface.
IPs []commonv1alpha1.IP
// VirtualIP is the virtual ip allocated for the network interface.
VirtualIP *commonv1alpha1.IP
}

// NetworkInterfacePhase represents the binding phase a NetworkInterface can be in.
type NetworkInterfacePhase string

const (
// NetworkInterfacePhasePending is used for a NetworkInterface that is not yet bound.
NetworkInterfacePhasePending NetworkInterfacePhase = "Pending"
// NetworkInterfacePhaseBound is used for a NetworkInterface that is bound.
NetworkInterfacePhaseBound NetworkInterfacePhase = "Bound"
)

// VolumeStatus is the status of a Volume.
type VolumeStatus struct {
// Name is the name of a volume attachment.
Name string
// Phase represents the binding phase of a Volume.
Phase VolumePhase
// DeviceID is the disk device ID on the host.
DeviceID string
}

// VolumePhase represents the binding phase a Volume can be in.
type VolumePhase string

const (
// VolumePhasePending is used for a Volume that is not yet bound.
VolumePhasePending VolumePhase = "Pending"
// VolumePhaseBound is used for a Volume that is bound.
VolumePhaseBound VolumePhase = "Bound"
)

// MachineStatus defines the observed state of Machine
type MachineStatus struct {
// State is the state of the machine.
Expand Down
8 changes: 8 additions & 0 deletions apis/compute/v1alpha1/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package v1alpha1

import (
networkingv1alpha1 "github.com/onmetal/onmetal-api/apis/networking/v1alpha1"
storagev1alpha1 "github.com/onmetal/onmetal-api/apis/storage/v1alpha1"
)

// EphemeralNetworkInterfaceSource is a definition for an ephemeral (i.e. coupled to the lifetime of the surrounding
Expand All @@ -24,3 +25,10 @@ type EphemeralNetworkInterfaceSource struct {
// NetworkInterfaceTemplate is the template definition of the networking.NetworkInterface.
NetworkInterfaceTemplate *networkingv1alpha1.NetworkInterfaceTemplateSpec `json:"networkInterfaceTemplate,omitempty"`
}

// EphemeralVolumeSource is a definition for an ephemeral (i.e. coupled to the lifetime of the surrounding object)
// storage.Volume.
type EphemeralVolumeSource struct {
// VolumeTemplate is the template definition of the storage.Volume.
VolumeTemplate *storagev1alpha1.VolumeTemplateSpec `json:"volumeTemplate,omitempty"`
}
27 changes: 27 additions & 0 deletions apis/compute/v1alpha1/machine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ type VolumeSource struct {
VolumeRef *corev1.LocalObjectReference `json:"volumeRef,omitempty"`
// EmptyDisk instructs to use a Volume offered by the machine pool provider.
EmptyDisk *EmptyDiskVolumeSource `json:"emptyDisk,omitempty"`
// Ephemeral instructs to create an ephemeral (i.e. coupled to the lifetime of the surrounding object)
// Volume to use.
Ephemeral *EphemeralVolumeSource `json:"ephemeral,omitempty"`
}

// EmptyDiskVolumeSource is a volume that's offered by the machine pool provider.
Expand All @@ -109,20 +112,44 @@ type EmptyDiskVolumeSource struct {
type NetworkInterfaceStatus struct {
// Name is the name of the NetworkInterface to whom the status belongs to.
Name string `json:"name"`
// Phase is the NetworkInterface binding phase of the NetworkInterface.
Phase NetworkInterfacePhase `json:"phase,omitempty"`
// IPs are the ips allocated for the network interface.
IPs []commonv1alpha1.IP `json:"ips,omitempty"`
// VirtualIP is the virtual ip allocated for the network interface.
VirtualIP *commonv1alpha1.IP `json:"virtualIP,omitempty"`
}

// NetworkInterfacePhase represents the binding phase a NetworkInterface can be in.
type NetworkInterfacePhase string

const (
// NetworkInterfacePhasePending is used for a NetworkInterface that is not yet bound.
NetworkInterfacePhasePending NetworkInterfacePhase = "Pending"
// NetworkInterfacePhaseBound is used for a NetworkInterface that is bound.
NetworkInterfacePhaseBound NetworkInterfacePhase = "Bound"
)

// VolumeStatus is the status of a Volume.
type VolumeStatus struct {
// Name is the name of a volume attachment.
Name string `json:"name"`
// Phase represents the binding phase of a Volume.
Phase VolumePhase `json:"phase,omitempty"`
// DeviceID is the disk device ID on the host.
DeviceID string `json:"deviceID,omitempty"`
}

// VolumePhase represents the binding phase a Volume can be in.
type VolumePhase string

const (
// VolumePhasePending is used for a Volume that is not yet bound.
VolumePhasePending VolumePhase = "Pending"
// VolumePhaseBound is used for a Volume that is bound.
VolumePhaseBound VolumePhase = "Bound"
)

// MachineStatus defines the observed state of Machine
type MachineStatus struct {
// State is the state of the machine.
Expand Down
38 changes: 38 additions & 0 deletions apis/compute/v1alpha1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions apis/compute/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions apis/compute/validation/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package validation
import (
onmetalapivalidation "github.com/onmetal/onmetal-api/api/validation"
"github.com/onmetal/onmetal-api/apis/compute"
"github.com/onmetal/onmetal-api/apis/storage"
storagevalidation "github.com/onmetal/onmetal-api/apis/storage/validation"
corev1 "k8s.io/api/core/v1"
apivalidation "k8s.io/apimachinery/pkg/api/validation"
metav1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
Expand Down Expand Up @@ -117,6 +119,14 @@ func validateVolumeSource(source *compute.VolumeSource, fldPath *field.Path) fie
allErrs = append(allErrs, validateEmptyDiskVolumeSource(source.EmptyDisk, fldPath.Child("emptyDisk"))...)
}
}
if source.Ephemeral != nil {
if numDefs > 0 {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("ephemeral"), "must only specify one volume source"))
} else {
numDefs++
allErrs = append(allErrs, validateEphemeralVolumeSource(source.Ephemeral, fldPath.Child("ephemeral"))...)
}
}
if numDefs == 0 {
allErrs = append(allErrs, field.Invalid(fldPath, source, "must specify at least one volume source"))
}
Expand All @@ -134,6 +144,37 @@ func validateEmptyDiskVolumeSource(source *compute.EmptyDiskVolumeSource, fldPat
return allErrs
}

func validateEphemeralVolumeSource(source *compute.EphemeralVolumeSource, fldPath *field.Path) field.ErrorList {
var allErrs field.ErrorList

if source.VolumeTemplate == nil {
allErrs = append(allErrs, field.Required(fldPath.Child("volumeTemplate"), "must specify volume template"))
} else {
allErrs = append(allErrs, validateVolumeTemplateSpecForMachine(source.VolumeTemplate, fldPath.Child("volumeTemplate"))...)
}

return allErrs
}

func validateVolumeTemplateSpecForMachine(template *storage.VolumeTemplateSpec, fldPath *field.Path) field.ErrorList {
var allErrs field.ErrorList

if template == nil {
allErrs = append(allErrs, field.Required(fldPath, ""))
} else {
allErrs = append(allErrs, storagevalidation.ValidateVolumeTemplateSpec(template, fldPath)...)

if template.Spec.ClaimRef != nil {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("spec", "claimRef"), "may not specify claimRef"))
}
if template.Spec.Unclaimable {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("spec", "unclaimable"), "may not specify unclaimable"))
}
}

return allErrs
}

// validateMachineSpecUpdate validates the spec of a Machine object before an update.
func validateMachineSpecUpdate(new, old *compute.MachineSpec, deletionTimestampSet bool, fldPath *field.Path) field.ErrorList {
var allErrs field.ErrorList
Expand Down
Loading

0 comments on commit b7693b7

Please sign in to comment.