Skip to content
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

feat(vd): crd generation #524

Merged
merged 1 commit into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 92 additions & 20 deletions api/core/v1alpha2/virtual_disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,20 @@ const (
VirtualDiskResource = "virtualdisks"
)

// VirtualDisk is a disk ready to be bound by a VM
// The `VirtualDisk` resource describes the desired virtual machine disk configuration. A `VirtualDisk` can be mounted statically in the virtual machine by specifying it in the `.spec.blockDeviceRefs` disk list, or mounted on-the-fly using the `VirtualMachineBlockDeviceAttachments` resource.
//
// Once `VirtualDisk` is created, only the disk size `.spec.persistentVolumeClaim.size` can be changed, all other fields are immutable.
// +kubebuilder:object:root=true
// +kubebuilder:metadata:labels={heritage=deckhouse,module=virtualization}
// +kubebuilder:resource:categories={virtualization,all},scope=Namespaced,shortName={vd,vds},singular=virtualdisk
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase`
// +kubebuilder:printcolumn:name="Capacity",type=string,JSONPath=`.status.capacity`
// +kubebuilder:printcolumn:name="Progress",type=string,JSONPath=`.status.progress`,priority=1
// +kubebuilder:printcolumn:name="StorageClass",type=string,JSONPath=`.spec.persistentVolumeClaim.storageClassName`,priority=1
// +kubebuilder:printcolumn:name="TargetPVC",type=string,JSONPath=`.status.target.persistentVolumeClaimName`,priority=1
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
// +kubebuilder:validation:XValidation:rule="self.metadata.name.size() <= 128",message="The name must be no longer than 128 characters."
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type VirtualDisk struct {
Expand All @@ -40,40 +53,60 @@ type VirtualDisk struct {

type VirtualDiskSpec struct {
DataSource *VirtualDiskDataSource `json:"dataSource,omitempty"`
PersistentVolumeClaim VirtualDiskPersistentVolumeClaim `json:"persistentVolumeClaim"`
PersistentVolumeClaim VirtualDiskPersistentVolumeClaim `json:"persistentVolumeClaim,omitempty"`
}

type VirtualDiskStatus struct {
DownloadSpeed *StatusSpeed `json:"downloadSpeed,omitempty"`
Capacity string `json:"capacity,omitempty"`
Target DiskTarget `json:"target"`
Progress string `json:"progress,omitempty"`
// Requested capacity of the PVC in human-readable format.
// +kubebuilder:example:="50G"
Capacity string `json:"capacity,omitempty"`
Target DiskTarget `json:"target,omitempty"`
// Progress of copying an image from source to PVC. Appears only during the `Provisioning' phase.
Progress string `json:"progress,omitempty"`
// Deprecated: use ImageUploadURLs instead.
UploadCommand string `json:"uploadCommand,omitempty"`
ImageUploadURLs *ImageUploadURLs `json:"imageUploadURLs,omitempty"`
Phase DiskPhase `json:"phase"`
UploadCommand string `json:"uploadCommand,omitempty"`
ImageUploadURLs *ImageUploadURLs `json:"imageUploadURLs,omitempty"`
Phase DiskPhase `json:"phase,omitempty"`
// A list of `VirtualMachines` that use the disk
// +kubebuilder:example:={{name: VM100}}
AttachedToVirtualMachines []AttachedVirtualMachine `json:"attachedToVirtualMachines,omitempty"`
Stats VirtualDiskStats `json:"stats"`
Stats VirtualDiskStats `json:"stats,omitempty"`
SourceUID *types.UID `json:"sourceUID,omitempty"`
Conditions []metav1.Condition `json:"conditions,omitempty"`
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
StorageClassName string `json:"storageClassName,omitempty"`
// The latest available observations of an object's current state.
Conditions []metav1.Condition `json:"conditions,omitempty"`
// The generation last processed by the controller.
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
// The name of the StorageClass used by the PersistentVolumeClaim if `Kubernetes` storage type used.
StorageClassName string `json:"storageClassName,omitempty"`
}

// VirtualDisk statistics
type VirtualDiskStats struct {
CreationDuration VirtualDiskStatsCreationDuration `json:"creationDuration"`
// The waiting time for the virtual disk creation.
CreationDuration VirtualDiskStatsCreationDuration `json:"creationDuration,omitempty"`
}

type VirtualDiskStatsCreationDuration struct {
// The waiting time for dependent resources.
// +nullable
WaitingForDependencies *metav1.Duration `json:"waitingForDependencies,omitempty"`
DVCRProvisioning *metav1.Duration `json:"dvcrProvisioning,omitempty"`
TotalProvisioning *metav1.Duration `json:"totalProvisioning,omitempty"`
// Duration of the loading into DVCR.
// +nullable
DVCRProvisioning *metav1.Duration `json:"dvcrProvisioning,omitempty"`
// The duration of resource creation from the moment dependencies are ready until the resource transitions to the Ready state.
// +nullable
TotalProvisioning *metav1.Duration `json:"totalProvisioning,omitempty"`
}

// A list of `VirtualMachines` that use the disk
type AttachedVirtualMachine struct {
Name string `json:"name"`
Name string `json:"name,omitempty"`
}

// +kubebuilder:validation:XValidation:rule="self.type == 'HTTP' ? has(self.http) && !has(self.containerImage) && !has(self.objectRef) : true",message="HTTP requires http and cannot have ContainerImage or ObjectRef"
// +kubebuilder:validation:XValidation:rule="self.type == 'ContainerImage' ? has(self.containerImage) && !has(self.http) && !has(self.objectRef) : true",message="ContainerImage requires containerImage and cannot have HTTP or ObjectRef"
// +kubebuilder:validation:XValidation:rule="self.type == 'ObjectRef' ? has(self.objectRef) && !has(self.http) && !has(self.containerImage) : true",message="ObjectRef requires objectRef and cannot have HTTP or ContainerImage"
type VirtualDiskDataSource struct {
Type DataSourceType `json:"type,omitempty"`
HTTP *DataSourceHTTP `json:"http,omitempty"`
Expand All @@ -93,11 +126,15 @@ type VirtualDiskContainerImage struct {
CABundle []byte `json:"caBundle,omitempty"`
}

// Use an existing `VirtualImage`, `ClusterVirtualImage` or `VirtualDiskSnapshot` to create a disk.
type VirtualDiskObjectRef struct {
Kind VirtualDiskObjectRefKind `json:"kind,omitempty"`
Name string `json:"name,omitempty"`
// A kind of existing `VirtualImage`, `ClusterVirtualImage` or `VirtualDiskSnapshot`.
Kind VirtualDiskObjectRefKind `json:"kind"`
// A name of existing `VirtualImage`, `ClusterVirtualImage` or `VirtualDiskSnapshot`.
Name string `json:"name"`
}

// +kubebuilder:validation:Enum:={ClusterVirtualImage,VirtualImage,VirtualDiskSnapshot}
type VirtualDiskObjectRefKind string

const (
Expand All @@ -107,12 +144,36 @@ const (
)

type DiskTarget struct {
// Created PersistentVolumeClaim name for Kubernetes storage.
PersistentVolumeClaim string `json:"persistentVolumeClaimName,omitempty"`
}

// Settings for creating PVCs to store the disk.
type VirtualDiskPersistentVolumeClaim struct {
StorageClass *string `json:"storageClassName,omitempty"`
Size *resource.Quantity `json:"size,omitempty"`
// The name of the StorageClass required by the claim. More info — https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
//
// When creating disks, the user can specify the required StorageClass to create the disk, or not explicitly, in which case the default StorageClass will be used.
//
// The disk features and virtual machine behavior depend on the selected StorageClass.
//
// The `VolumeBindingMode` parameter in the StorageClass affects the disk creation process:
// - `Immediate` - The disk will be created and available for use immediately after creation.
// - `WaitForFirstConsumer` - The disk will be created only when it is used in a virtual machine. In this case, the disk will be created on the host where the virtual machine will be started.
//
// StorageClass can support different storage settings:
// - Creating a block device (`Block`) or file system (`FileSystem`).
// - Multiple Access (`ReadWriteMany`) or Single Access (`ReadWriteOnce`). `ReadWriteMany` disks support multiple access, which enables live migration of virtual machines. In contrast, `ReadWriteOnce` disks, which are limited to access from only one host, cannot provide this capability.
//
// For known storage types, the platform will independently determine the most effective settings when creating disks (in descending order of priority):
// 1. `Block` + `ReadWriteMany`
// 2. `FileSystem` + `ReadWriteMany`
// 3. `Block` + `ReadWriteOnce`
// 4. `FileSystem` + `ReadWriteOnce`
StorageClass *string `json:"storageClassName,omitempty"`
// Desired size for PVC to store the disk. If the disk is created from an image, the size must be at least as large as the original unpacked image.
//
// This parameter can be omitted if the `.spec.dataSource` block is specified, in which case the controller will determine the disk size automatically, based on the size of the extracted image from the source specified in `.spec.dataSource`.
Size *resource.Quantity `json:"size,omitempty"`
}

// VirtualDiskList contains a list of VirtualDisk
Expand All @@ -123,6 +184,17 @@ type VirtualDiskList struct {
Items []VirtualDisk `json:"items"`
}

// Current status of `VirtualDisk` resource:
// * Pending - The resource has been created and is on a waiting queue.
// * Provisioning - The process of resource creation (copying/downloading/filling the PVC with data/extending PVC) is in progress.
// * WaitForUserUpload - Waiting for the user to upload the image. The endpoint to upload the image is specified in `.status.uploadCommand`.
// * WaitForFirstConsumer - Waiting for the virtual machine that uses the disk is scheduled.
// * Ready - The resource is created and ready to use.
// * Resizing — The process of resource resizing is in progress.
// * Failed - There was a problem when creating a resource.
// * PVCLost - The child PVC of the resource is missing. The resource cannot be used.
// * Terminating - The process of resource deletion is in progress.
// +kubebuilder:validation:Enum:={Pending,Provisioning,WaitForUserUpload,Ready,Failed,Terminating,PVCLost,WaitForFirstConsumer,Resizing}
type DiskPhase string

const (
Expand Down
Loading
Loading