Skip to content

Commit

Permalink
feat(vmbda): apply new design
Browse files Browse the repository at this point in the history
Signed-off-by: Isteb4k <[email protected]>
  • Loading branch information
Isteb4k committed Jul 1, 2024
1 parent e1d197d commit a264b6d
Show file tree
Hide file tree
Showing 24 changed files with 975 additions and 790 deletions.
23 changes: 10 additions & 13 deletions api/core/v1alpha2/virtual_machine_block_disk_attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ type VirtualMachineBlockDeviceAttachmentList struct {
}

type VirtualMachineBlockDeviceAttachmentSpec struct {
VirtualMachine string `json:"virtualMachineName"`
BlockDeviceRef VMBDAObjectRef `json:"blockDeviceRef"`
VirtualMachineName string `json:"virtualMachineName"`
BlockDeviceRef VMBDAObjectRef `json:"blockDeviceRef"`
}

type VMBDAObjectRef struct {
Expand All @@ -60,21 +60,18 @@ const (
VMBDAObjectRefKindVirtualDisk VMBDAObjectRefKind = "VirtualDisk"
)

type VirtualMachineBlockDeviceAttachmentObjectRefKind string

const BlockDeviceAttachmentTypeVirtualDisk VirtualMachineBlockDeviceAttachmentObjectRefKind = "VirtualDisk"

type VirtualMachineBlockDeviceAttachmentStatus struct {
VirtualMachine string `json:"virtualMachine,omitempty"`
Phase BlockDeviceAttachmentPhase `json:"phase,omitempty"`
FailureReason string `json:"failureReason,omitempty"`
FailureMessage string `json:"failureMessage,omitempty"`
Phase BlockDeviceAttachmentPhase `json:"phase,omitempty"`
Conditions []metav1.Condition `json:"conditions,omitempty"`
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
}

type BlockDeviceAttachmentPhase string

const (
BlockDeviceAttachmentPhaseInProgress BlockDeviceAttachmentPhase = "InProgress"
BlockDeviceAttachmentPhaseAttached BlockDeviceAttachmentPhase = "Attached"
BlockDeviceAttachmentPhaseFailed BlockDeviceAttachmentPhase = "Failed"
BlockDeviceAttachmentPhasePending BlockDeviceAttachmentPhase = "Pending"
BlockDeviceAttachmentPhaseInProgress BlockDeviceAttachmentPhase = "InProgress"
BlockDeviceAttachmentPhaseAttached BlockDeviceAttachmentPhase = "Attached"
BlockDeviceAttachmentPhaseFailed BlockDeviceAttachmentPhase = "Failed"
BlockDeviceAttachmentPhaseTerminating BlockDeviceAttachmentPhase = "Terminating"
)
44 changes: 44 additions & 0 deletions api/core/v1alpha2/vmbdacondition/condition.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
Copyright 2024 Flant JSC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package vmbdacondition

type Type = string

const (
BlockDeviceReadyType Type = "BlockDeviceReady"
VirtualMachineReadyType Type = "VirtualMachineReady"
AttachedType Type = "Attached"
)

type (
BlockDeviceReadyReason = string
VirtualMachineReadyReason = string
AttachedReason = string
)

const (
BlockDeviceReady BlockDeviceReadyReason = "BlockDeviceReady"
BlockDeviceNotReady BlockDeviceReadyReason = "BlockDeviceNotReady"

VirtualMachineReady VirtualMachineReadyReason = "VirtualMachineReady"
VirtualMachineNotReady VirtualMachineReadyReason = "VirtualMachineNotReady"

Attached AttachedReason = "Attached"
NotAttached AttachedReason = "NotAttached"
AttachmentRequestSent AttachedReason = "AttachmentRequestSent"
AttachmentFailed AttachedReason = "AttachmentFailed"
)
9 changes: 8 additions & 1 deletion api/core/v1alpha2/zz_generated.deepcopy.go

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

27 changes: 1 addition & 26 deletions api/pkg/apiserver/api/generated/openapi/zz_generated.openapi.go

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

2 changes: 1 addition & 1 deletion crds/doc-ru-virtualdisk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ spec:
* Ready — ресурс создан и готов к использованию.
* Resizing — идет процесс увеличения размера диска.
* Failed — при создании ресурса возникла проблема.
* PVCLost — дочерний PVC ресурса отсутствует. Ресурс не может быть использован.
* PVCLost — дочерний PVC ресурса отсутствует.
* Terminating - Ресурс находится в процессе удаления.
progress:
description: |
Expand Down
4 changes: 3 additions & 1 deletion crds/doc-ru-virtualmachineblockdeviceattachment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ spec:
description: |
Фаза ресурса:
* Pending — ресурс был создан и находится в очереди ожидания.
* InProgress — диск в процессе подключения к ВМ.
* Attached — диск подключен к ВМ.
* Failed — возникла проблема с подключением диска. Смотрите `.status.failureReason`.
* Failed — возникла проблема с подключением диска.
* Terminating - Ресурс находится в процессе удаления.
virtualMachineName:
description: |
Имя виртуальной машины, к которой подключен этот диск.
2 changes: 1 addition & 1 deletion crds/virtualdisk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ spec:
* WaitForUserUpload - Waiting for the user to upload the image. The endpoint to upload the image is specified in `.status.uploadCommand`.
* 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, details can be seen in `.status.failureReason` and `.status.failureMessage`.
* 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.
enum:
Expand Down
6 changes: 5 additions & 1 deletion crds/virtualmachineblockdeviceattachment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,17 @@ spec:
description: |
Represents the current phase of resource:
* Pending - the resource has been created and is on a waiting queue.
* InProgress - the disk is in the process of being attached.
* Attached - the disk is attached to virtual machine.
* Failed - there was a problem with attaching the disk. See `.status.failureReason`.
* Failed - there was a problem with attaching the disk.
* Terminating - The process of resource deletion is in progress.
enum:
- "Pending"
- "InProgress"
- "Attached"
- "Failed"
- "Terminating"
failureReason:
type: string
description: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ import (

"github.com/deckhouse/virtualization-controller/pkg/common"
appconfig "github.com/deckhouse/virtualization-controller/pkg/config"
"github.com/deckhouse/virtualization-controller/pkg/controller"
"github.com/deckhouse/virtualization-controller/pkg/controller/cpu"
"github.com/deckhouse/virtualization-controller/pkg/controller/cvi"
"github.com/deckhouse/virtualization-controller/pkg/controller/ipam"
"github.com/deckhouse/virtualization-controller/pkg/controller/vd"
"github.com/deckhouse/virtualization-controller/pkg/controller/vi"
"github.com/deckhouse/virtualization-controller/pkg/controller/vm"
"github.com/deckhouse/virtualization-controller/pkg/controller/vmbda"
"github.com/deckhouse/virtualization-controller/pkg/controller/vmop"
virtv2alpha1 "github.com/deckhouse/virtualization/api/core/v1alpha2"
)
Expand Down Expand Up @@ -188,16 +188,16 @@ func main() {
os.Exit(1)
}

if _, err := vi.NewController(ctx, mgr, log, importerImage, uploaderImage, dvcrSettings); err != nil {
if _, err = vi.NewController(ctx, mgr, log, importerImage, uploaderImage, dvcrSettings); err != nil {
log.Error(err, "")
os.Exit(1)
}
if _, err := vm.NewController(ctx, mgr, slog.Default(), dvcrSettings); err != nil {
if _, err = vm.NewController(ctx, mgr, slog.Default(), dvcrSettings); err != nil {
log.Error(err, "")
os.Exit(1)
}

if _, err := controller.NewVMBDAController(ctx, mgr, log, controllerNamespace); err != nil {
if _, err = vmbda.NewController(ctx, mgr, log, controllerNamespace); err != nil {
log.Error(err, "")
os.Exit(1)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*
Copyright 2024 Flant JSC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package service

import (
"context"
"errors"
"fmt"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
virtv1 "kubevirt.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/deckhouse/virtualization-controller/pkg/controller/kubevirt"
"github.com/deckhouse/virtualization-controller/pkg/controller/kvapi"
"github.com/deckhouse/virtualization-controller/pkg/controller/kvbuilder"
"github.com/deckhouse/virtualization-controller/pkg/sdk/framework/helper"
virtv2 "github.com/deckhouse/virtualization/api/core/v1alpha2"
)

type AttachmentService struct {
client client.Client
controllerNamespace string
}

func NewAttachmentService(client client.Client, controllerNamespace string) *AttachmentService {
return &AttachmentService{
client: client,
controllerNamespace: controllerNamespace,
}
}

func (s AttachmentService) IsHotPlugged(ctx context.Context, vd *virtv2.VirtualDisk, vm *virtv2.VirtualMachine) (bool, error) {
if vd == nil || vm == nil {
return false, errors.New("TODO")
}

// TODO: get errors from xvm/xvmi.
// TODO: kvvmi not found or not ready? Check kvvm instead of kvvmi?
kvvmKey := types.NamespacedName{Namespace: vm.Namespace, Name: vm.Name}
kvvm, err := helper.FetchObject(ctx, kvvmKey, s.client, &virtv1.VirtualMachine{})
if err != nil {
return false, err
}
if kvvm == nil {
return false, fmt.Errorf("kvvm %s not found", kvvmKey.String())
}

if kvvm.Spec.Template == nil {
return false, nil
}

for _, volume := range kvvm.Spec.Template.Spec.Volumes {
if volume.Name == kvbuilder.GenerateVMDDiskName(vd.Name) {
return volume.PersistentVolumeClaim != nil && volume.PersistentVolumeClaim.Hotpluggable, nil
}
}

return false, nil
}

var (
ErrVirtualDiskIsAlreadyAttached = errors.New("virtual disk is already attached to virtual machine")
ErrVirtualMachineWaitsForRestartApproval = errors.New("virtual machine waits for restart approval")
)

func (s AttachmentService) HotPlugDisk(ctx context.Context, vd *virtv2.VirtualDisk, vm *virtv2.VirtualMachine) error {
if vd == nil || vm == nil {
return errors.New("TODO")
}

for _, bdr := range vm.Spec.BlockDeviceRefs {
if bdr.Kind == virtv2.DiskDevice && bdr.Name == vd.Name {
return ErrVirtualDiskIsAlreadyAttached
}
}

if len(vm.Status.RestartAwaitingChanges) > 0 {
return ErrVirtualMachineWaitsForRestartApproval
}

name := kvbuilder.GenerateVMDDiskName(vd.Name)

hotplugRequest := virtv1.AddVolumeOptions{
Name: name,
Disk: &virtv1.Disk{
Name: name,
DiskDevice: virtv1.DiskDevice{
Disk: &virtv1.DiskTarget{
Bus: "scsi",
},
},
Serial: vd.Name,
},
VolumeSource: &virtv1.HotplugVolumeSource{
PersistentVolumeClaim: &virtv1.PersistentVolumeClaimVolumeSource{
PersistentVolumeClaimVolumeSource: corev1.PersistentVolumeClaimVolumeSource{
ClaimName: vd.Status.Target.PersistentVolumeClaim,
},
Hotpluggable: true,
},
},
}

kv, err := kubevirt.New(ctx, s.client, s.controllerNamespace)
if err != nil {
return err
}

err = kvapi.New(s.client, kv).AddVolume(ctx, vm.Namespace, vm.Name, &hotplugRequest)
if err != nil {
return fmt.Errorf("error adding volume, %w", err)
}

return nil
}

func (s AttachmentService) UnplugDisk(ctx context.Context, vd *virtv2.VirtualDisk, vm *virtv2.VirtualMachine) error {
if vd == nil || vm == nil {
return errors.New("TODO")
}

unplugRequest := virtv1.RemoveVolumeOptions{
Name: kvbuilder.GenerateVMDDiskName(vd.Name),
}

kv, err := kubevirt.New(ctx, s.client, s.controllerNamespace)
if err != nil {
return err
}

err = kvapi.New(s.client, kv).RemoveVolume(ctx, vm.Namespace, vm.Name, &unplugRequest)
if err != nil {
return fmt.Errorf("error removing volume, %w", err)
}

return nil
}

func (s AttachmentService) GetVirtualDisk(ctx context.Context, name, namespace string) (*virtv2.VirtualDisk, error) {
return helper.FetchObject(ctx, types.NamespacedName{Namespace: name, Name: namespace}, s.client, &virtv2.VirtualDisk{})
}

func (s AttachmentService) GetVirtualMachine(ctx context.Context, name, namespace string) (*virtv2.VirtualMachine, error) {
return helper.FetchObject(ctx, types.NamespacedName{Namespace: name, Name: namespace}, s.client, &virtv2.VirtualMachine{})
}
Loading

0 comments on commit a264b6d

Please sign in to comment.