Skip to content

Commit

Permalink
fix(api): resolve comments
Browse files Browse the repository at this point in the history
Signed-off-by: Isteb4k <dmitry.rakitin@flant.com>
  • Loading branch information
Isteb4k committed Aug 29, 2024
1 parent 21a4f77 commit fb0cbed
Show file tree
Hide file tree
Showing 24 changed files with 330 additions and 148 deletions.
7 changes: 5 additions & 2 deletions api/client/kubeclient/async.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,11 @@ func (a *AsyncSubresourceError) GetStatusCode() int {
}

// params are strings with "key=value" format
func asyncSubresourceHelper(config *rest.Config, resource, namespace, name, subresource string,
queryParams url.Values) (StreamInterface, error) {
func asyncSubresourceHelper(
config *rest.Config,
resource, namespace, name, subresource string,
queryParams url.Values,
) (StreamInterface, error) {
done := make(chan struct{})

aws := &asyncWSRoundTripper{
Expand Down
3 changes: 3 additions & 0 deletions api/client/kubeclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package kubeclient

import (
"context"
"io"
"net"

Expand Down Expand Up @@ -79,6 +80,8 @@ type VirtualMachineInterface interface {
SerialConsole(name string, options *SerialConsoleOptions) (StreamInterface, error)
VNC(name string) (StreamInterface, error)
PortForward(name string, opts v1alpha2.VirtualMachinePortForward) (StreamInterface, error)
Freeze(ctx context.Context, name string, opts v1alpha2.VirtualMachineFreeze) error
Unfreeze(ctx context.Context, name string) error
}

type client struct {
Expand Down
39 changes: 39 additions & 0 deletions api/client/kubeclient/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,18 @@ Initially copied from https://github.com/kubevirt/kubevirt/blob/main/staging/src
package kubeclient

import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
"strconv"
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/rest"
virtv1 "kubevirt.io/api/core/v1"

virtualizationv1alpha2 "github.com/deckhouse/virtualization/api/client/generated/clientset/versioned/typed/core/v1alpha2"
"github.com/deckhouse/virtualization/api/subresources/v1alpha2"
Expand Down Expand Up @@ -106,3 +110,38 @@ func (v vm) PortForward(name string, opts v1alpha2.VirtualMachinePortForward) (S
}
return asyncSubresourceHelper(v.config, v.resource, v.namespace, name, "portforward", params)
}

func (v vm) Freeze(ctx context.Context, name string, opts v1alpha2.VirtualMachineFreeze) error {
path := fmt.Sprintf(operationURLTpl, v.namespace, v.resource, name, "freeze")

unfreezeTimeout := virtv1.FreezeUnfreezeTimeout{
UnfreezeTimeout: &metav1.Duration{},
}

if opts.UnfreezeTimeout != nil {
unfreezeTimeout.UnfreezeTimeout = opts.UnfreezeTimeout
}

body, err := json.Marshal(&unfreezeTimeout)
if err != nil {
return err
}

err = v.restClient.Put().AbsPath(path).Body(body).Do(ctx).Error()
if err != nil {
return err
}

return nil
}

func (v vm) Unfreeze(ctx context.Context, name string) error {
path := fmt.Sprintf(operationURLTpl, v.namespace, v.resource, name, "unfreeze")

err := v.restClient.Put().AbsPath(path).Do(ctx).Error()
if err != nil {
return err
}

return nil
}
7 changes: 4 additions & 3 deletions api/core/v1alpha2/virtual_disk_snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,15 @@ type VirtualDiskSnapshotList struct {
}

type VirtualDiskSnapshotSpec struct {
VirtualDiskName string `json:"virtualDiskName"`
VolumeSnapshotClassName string `json:"volumeSnapshotClassName"`
AllowPotentiallyInconsistent bool `json:"allowPotentiallyInconsistent"`
VirtualDiskName string `json:"virtualDiskName"`
VolumeSnapshotClassName string `json:"volumeSnapshotClassName"`
RequiredConsistency bool `json:"requiredConsistency"`
}

type VirtualDiskSnapshotStatus struct {
Phase VirtualDiskSnapshotPhase `json:"phase"`
VolumeSnapshotName string `json:"volumeSnapshotName,omitempty"`
Consistent *bool `json:"consistent,omitempty"`
Conditions []metav1.Condition `json:"conditions,omitempty"`
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
}
Expand Down
5 changes: 5 additions & 0 deletions api/core/v1alpha2/zz_generated.deepcopy.go

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

10 changes: 8 additions & 2 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.

11 changes: 7 additions & 4 deletions crds/doc-ru-virtualdisksnapshot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ spec:
description: |
Предоставляет ресурс для создания снимков существующих виртуальных дисков, которые могут быть использованы в качестве источников данных для создания новых виртуальных дисков.
Под капотом автоматически создается ресурс `VolumeSnapshot`.
В процессе выполнения автоматически создается ресурс `VolumeSnapshot`.
properties:
spec:
properties:
Expand All @@ -16,11 +16,11 @@ spec:
volumeSnapshotClassName:
description: |
Имя класса снимков томов, который будет использоваться при создании снимка виртуального диска.
allowPotentiallyInconsistent:
requiredConsistency:
description: |
Разрешать ли создание снимка диска виртуальной машины, подключенного к работающей виртуальной машине без агента, которую нет возможности заморозить.
Создавать снимок диска подключённой виртуальной машины только в том случае, если возможно заморозить её через агента.
Если значение установлено в false, снимок виртуального диска будет создан только в следующих случаях:
Если значение установлено в true, снимок виртуального диска будет создан только в следующих случаях:
- виртуальный диск не подключен ни к одной виртуальной машине;
- виртуальный диск подключен к виртуальной машине, которая выключена;
- виртуальный диск подключен к виртуальной машине с агентом, и операция заморозки прошла успешно.
Expand All @@ -47,6 +47,9 @@ spec:
volumeSnapshotName:
description: |
Имя созданного ресурса `VolumeSnapshot`.
consistent:
description: |
Снимок виртуального диска консистентен.
phase:
description: |
Текущее состояние ресурса `VirtualDiskSnapshot`:
Expand Down
18 changes: 14 additions & 4 deletions crds/virtualdisksnapshot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ spec:
type: string
description: |
The name of the volume snapshot class to use while snapshotting virtual disk.
allowPotentiallyInconsistent:
requiredConsistency:
type: boolean
default: false
default: true
description: |
Specify whether to allow the snapshotting of a virtual machine's disk that is attached to a running virtual machine without an agent, and as a result, cannot be frozen.
Create a snapshot of a connected virtual machine's disk only if it is possible to freeze the machine through the agent.
If value is false, the snapshot of the virtual disk will be taken only in the following scenarios:
If value is true, the snapshot of the virtual disk will be taken only in the following scenarios:
- the virtual disk is not attached to any virtual machine.
- the virtual disk is attached to a virtual machine that is powered off.
- the virtual disk is attached to a virtual machine with an agent, and the freeze operation was successful.
Expand Down Expand Up @@ -95,6 +95,10 @@ spec:
type: string
description: |
The name of the `VolumeSnapshot` created automatically by this resource.
consistent:
type: boolean
description: |
The virtual disk snapshot is consistent.
phase:
type: string
description: |
Expand All @@ -115,5 +119,11 @@ spec:
- name: Phase
type: string
jsonPath: .status.phase
- name: Consistent
type: boolean
jsonPath: .status.consistent
- name: Age
type: date
jsonPath: .metadata.creationTimestamp
subresources:
status: {}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiruntime "k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
virtv1 "kubevirt.io/api/core/v1"
cdiv1beta1 "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/client/config"
Expand All @@ -50,6 +49,7 @@ import (
"github.com/deckhouse/virtualization-controller/pkg/controller/vmiplease"
"github.com/deckhouse/virtualization-controller/pkg/controller/vmop"
"github.com/deckhouse/virtualization-controller/pkg/logger"
"github.com/deckhouse/virtualization/api/client/kubeclient"
virtv2alpha1 "github.com/deckhouse/virtualization/api/core/v1alpha2"
)

Expand Down Expand Up @@ -191,7 +191,7 @@ func main() {
os.Exit(1)
}

restClient, err := rest.UnversionedRESTClientFor(cfg)
virtClient, err := kubeclient.GetClientFromRESTConfig(cfg)
if err != nil {
log.Error(err.Error())
os.Exit(1)
Expand Down Expand Up @@ -251,16 +251,15 @@ func main() {
os.Exit(1)
}

if _, err = vmop.NewController(ctx, mgr, log); err != nil {
if _, err = vdsnapshot.NewController(ctx, mgr, log, virtClient); err != nil {
log.Error(err.Error())
os.Exit(1)
}

if _, err = vdsnapshot.NewController(ctx, mgr, log, restClient); err != nil {
if err = vmop.SetupController(ctx, mgr, log); err != nil {
log.Error(err.Error())
os.Exit(1)
}

if err = vmop.SetupGC(mgr, log, gcSettings.VMOP); err != nil {
log.Error(err.Error())
os.Exit(1)
Expand Down
3 changes: 2 additions & 1 deletion images/virtualization-artifact/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/onsi/ginkgo/v2 v2.14.0
github.com/onsi/gomega v1.30.0
github.com/prometheus/client_golang v1.18.0
github.com/robfig/cron/v3 v3.0.1
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.8.4
go.uber.org/zap v1.26.0
Expand Down Expand Up @@ -67,6 +68,7 @@ require (
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
Expand All @@ -89,7 +91,6 @@ require (
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,24 +56,6 @@ func (m *Manager) Update(c metav1.Condition) {
meta.SetStatusCondition(&m.conds, c)
}

type Conditioner interface {
Condition() metav1.Condition
}

// Update2 TODO will be refactored soon.
func (m *Manager) Update2(conditioner Conditioner) {
c := conditioner.Condition()

if i, found := m.indexConds[c.Type]; found {
if !equalConditions(c, m.conds[i]) {
m.conds[i] = c
}
return
}
m.conds = append(m.conds, c)
m.indexConds[c.Type] = len(m.conds) - 1
}

func (m *Manager) Generate() []metav1.Condition {
return slices.Clone(m.conds)
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const (
IndexFieldVMByCVI = "spec.blockDeviceRefs.ClusterVirtualImage"

IndexFieldVMIPLeaseByVMIP = "spec.virtualMachineIPAddressRef.Name"

IndexFieldVDByVDSnapshot = "spec.DataSource.ObjectRef.Name,.Kind=VirtualDiskSnapshot"
)

type indexFunc func(ctx context.Context, mgr manager.Manager) error
Expand All @@ -43,6 +45,7 @@ func IndexALL(ctx context.Context, mgr manager.Manager) error {
IndexVMByVI,
IndexVMByCVI,
IndexVMIPLeaseByVMIP,
IndexVDByVDSnapshot,
} {
if err := fn(ctx, mgr); err != nil {
return err
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
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 indexer

import (
"context"

"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/manager"

virtv2 "github.com/deckhouse/virtualization/api/core/v1alpha2"
)

func IndexVDByVDSnapshot(ctx context.Context, mgr manager.Manager) error {
return mgr.GetFieldIndexer().IndexField(ctx, &virtv2.VirtualDisk{}, IndexFieldVDByVDSnapshot, func(object client.Object) []string {
vd, ok := object.(*virtv2.VirtualDisk)
if !ok || vd == nil {
return nil
}

if vd.Spec.DataSource == nil || vd.Spec.DataSource.Type != virtv2.DataSourceTypeObjectRef {
return nil
}

if vd.Spec.DataSource.ObjectRef == nil || vd.Spec.DataSource.ObjectRef.Kind != virtv2.VirtualDiskObjectRefKindVirtualDiskSnapshot {
return nil
}

return []string{vd.Spec.DataSource.ObjectRef.Name}
})
}
Loading

0 comments on commit fb0cbed

Please sign in to comment.