Skip to content

Commit 46aaa23

Browse files
committed
init clone
Signed-off-by: Daniil Antoshin <[email protected]>
1 parent 4c5bcaa commit 46aaa23

File tree

19 files changed

+1021
-16
lines changed

19 files changed

+1021
-16
lines changed

api/core/v1alpha2/virtual_machine_operation.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ type VirtualMachineOperation struct {
4646
// +kubebuilder:validation:XValidation:rule="self.type == 'Start' ? !has(self.force) || !self.force : true",message="The `Start` operation cannot be performed forcibly."
4747
// +kubebuilder:validation:XValidation:rule="self.type == 'Migrate' ? !has(self.force) || !self.force : true",message="The `Migrate` operation cannot be performed forcibly."
4848
// +kubebuilder:validation:XValidation:rule="self.type == 'Restore' ? has(self.restore) : true",message="Restore requires restore field."
49+
// +kubebuilder:validation:XValidation:rule="self.type == 'Clone' ? has(self.clone) : true",message="Clone requires clone field."
4950
type VirtualMachineOperationSpec struct {
5051
Type VMOPType `json:"type"`
5152
// Name of the virtual machine the operation is performed for.
@@ -57,6 +58,8 @@ type VirtualMachineOperationSpec struct {
5758
Force *bool `json:"force,omitempty"`
5859
// Restore defines the restore operation.
5960
Restore *VirtualMachineOperationRestoreSpec `json:"restore,omitempty"`
61+
// Clone defines the clone operation.
62+
Clone *VirtualMachineOperationCloneSpec `json:"clone,omitempty"`
6063
}
6164

6265
// VirtualMachineOperationRestoreSpec defines the restore operation.
@@ -66,6 +69,14 @@ type VirtualMachineOperationRestoreSpec struct {
6669
VirtualMachineSnapshotName string `json:"virtualMachineSnapshotName"`
6770
}
6871

72+
// VirtualMachineOperationCloneSpec defines the clone operation.
73+
type VirtualMachineOperationCloneSpec struct {
74+
Mode VMOPRestoreMode `json:"mode"`
75+
// NameReplacement defines rules for renaming resources during cloning.
76+
// Note: This references the NameReplacement type from virtual_machine_restore.go
77+
NameReplacement []NameReplacement `json:"nameReplacement,omitempty"`
78+
}
79+
6980
// VMOPRestoreMode defines the kind of the restore operation.
7081
// * `DryRun`: DryRun run without any changes. Compatibility shows in status.
7182
// * `Strict`: Strict restore as is in the snapshot.
@@ -160,7 +171,8 @@ const (
160171
// * `Migrate` (deprecated): Migrate the virtual machine to another node where it can be started.
161172
// * `Evict`: Migrate the virtual machine to another node where it can be started.
162173
// * `Restore`: Restore the virtual machine from a snapshot.
163-
// +kubebuilder:validation:Enum={Restart,Start,Stop,Migrate,Evict,Restore}
174+
// * `Clone`: Clone the virtual machine to a new virtual machine.
175+
// +kubebuilder:validation:Enum={Restart,Start,Stop,Migrate,Evict,Restore,Clone}
164176
type VMOPType string
165177

166178
const (
@@ -170,4 +182,5 @@ const (
170182
VMOPTypeMigrate VMOPType = "Migrate"
171183
VMOPTypeEvict VMOPType = "Evict"
172184
VMOPTypeRestore VMOPType = "Restore"
185+
VMOPTypeClone VMOPType = "Clone"
173186
)

api/core/v1alpha2/vmopcondition/condition.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ const (
3232
// TypeRestoreCompleted is a type for condition that indicates success of restore.
3333
TypeRestoreCompleted Type = "RestoreCompleted"
3434

35+
// TypeCloneCompleted is a type for condition that indicates success of clone.
36+
TypeCloneCompleted Type = "CloneCompleted"
37+
3538
// TypeMaintenanceMode is a type for condition that indicates VMOP has put VM in maintenance mode.
3639
TypeMaintenanceMode Type = "MaintenanceMode"
3740
)
@@ -71,6 +74,9 @@ const (
7174
// ReasonRestoreInProgress is a ReasonCompleted indicating that the restore operation is in progress.
7275
ReasonRestoreInProgress ReasonCompleted = "RestoreInProgress"
7376

77+
// ReasonCloneInProgress is a ReasonCompleted indicating that the clone operation is in progress.
78+
ReasonCloneInProgress ReasonCompleted = "CloneInProgress"
79+
7480
// ReasonMigrationPending is a ReasonCompleted indicating that the migration process has been initiated but not yet started.
7581
ReasonMigrationPending ReasonCompleted = "MigrationPending"
7682

@@ -117,6 +123,24 @@ const (
117123
ReasonRestoreOperationFailed ReasonRestoreCompleted = "RestoreFailed"
118124
)
119125

126+
// ReasonCloneCompleted represents specific reasons for the 'CloneCompleted' condition type.
127+
type ReasonCloneCompleted string
128+
129+
func (r ReasonCloneCompleted) String() string {
130+
return string(r)
131+
}
132+
133+
const (
134+
// ReasonCloneOperationInProgress is a ReasonCloneCompleted indicating that the clone operation is in progress.
135+
ReasonCloneOperationInProgress ReasonCloneCompleted = "CloneInProgress"
136+
137+
// ReasonCloneOperationCompleted is a ReasonCloneCompleted indicating that the clone operation has completed successfully.
138+
ReasonCloneOperationCompleted ReasonCloneCompleted = "CloneCompleted"
139+
140+
// ReasonCloneOperationFailed is a ReasonCloneCompleted indicating that clone operation has failed.
141+
ReasonCloneOperationFailed ReasonCloneCompleted = "CloneFailed"
142+
)
143+
120144
// ReasonCompleted represents specific reasons for the 'SignalSent' condition type.
121145
type ReasonSignalSent string
122146

api/core/v1alpha2/zz_generated.deepcopy.go

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crds/virtualmachineoperations.yaml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,52 @@ spec:
6666
type: object
6767
spec:
6868
properties:
69+
clone:
70+
description: Clone defines the clone operation.
71+
properties:
72+
mode:
73+
description: |-
74+
VMOPRestoreMode defines the kind of the restore operation.
75+
* `DryRun`: DryRun run without any changes. Compatibility shows in status.
76+
* `Strict`: Strict restore as is in the snapshot.
77+
* `BestEffort`: BestEffort restore without deleted external missing dependencies.
78+
enum:
79+
- DryRun
80+
- Strict
81+
- BestEffort
82+
type: string
83+
nameReplacement:
84+
description: |-
85+
NameReplacement defines rules for renaming resources during cloning.
86+
Note: This references the NameReplacement type from virtual_machine_restore.go
87+
items:
88+
description:
89+
NameReplacement represents a rule for redefining
90+
the virtual machine resource names.
91+
properties:
92+
from:
93+
description: Selector to choose resources for name replacement.
94+
properties:
95+
kind:
96+
description: Kind of a resource to rename.
97+
type: string
98+
name:
99+
description: Current name of a resource to rename.
100+
type: string
101+
required:
102+
- name
103+
type: object
104+
to:
105+
description: New resource name.
106+
type: string
107+
required:
108+
- from
109+
- to
110+
type: object
111+
type: array
112+
required:
113+
- mode
114+
type: object
69115
force:
70116
description: |-
71117
Force execution of an operation.
@@ -105,13 +151,15 @@ spec:
105151
* `Migrate` (deprecated): Migrate the virtual machine to another node where it can be started.
106152
* `Evict`: Migrate the virtual machine to another node where it can be started.
107153
* `Restore`: Restore the virtual machine from a snapshot.
154+
* `Clone`: Clone the virtual machine to a new virtual machine.
108155
enum:
109156
- Restart
110157
- Start
111158
- Stop
112159
- Migrate
113160
- Evict
114161
- Restore
162+
- Clone
115163
type: string
116164
virtualMachineName:
117165
description:
@@ -133,6 +181,8 @@ spec:
133181
true"
134182
- message: Restore requires restore field.
135183
rule: "self.type == 'Restore' ? has(self.restore) : true"
184+
- message: Clone requires clone field.
185+
rule: "self.type == 'Clone' ? has(self.clone) : true"
136186
status:
137187
properties:
138188
conditions:

images/virtualization-artifact/pkg/apiserver/api/generated/openapi/zz_generated.openapi.go

Lines changed: 45 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
Copyright 2025 Flant JSC
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package common
18+
19+
import (
20+
"errors"
21+
"fmt"
22+
)
23+
24+
var (
25+
ErrVirtualMachineAlreadyExists = errors.New("VirtualMachine already exists")
26+
ErrVirtualDiskAlreadyExists = errors.New("VirtualDisk already exists")
27+
ErrVirtualDiskAttachedToDifferentVM = errors.New("VirtualDisk is attached to different VirtualMachine")
28+
ErrVMBDAAlreadyExists = errors.New("VirtualMachineBlockDeviceAttachment already exists")
29+
ErrVMBDAAttachedToDifferentVM = errors.New("VirtualMachineBlockDeviceAttachment is attached to different VirtualMachine")
30+
ErrVMIPAttachedToDifferentVM = errors.New("VirtualMachineIPAddress is attached to different VirtualMachine")
31+
ErrImageResourceNotFound = errors.New("image resource is used by VirtualMachine but absent in cluster")
32+
ErrSecretContentDifferent = errors.New("secret content is different from that in the snapshot")
33+
)
34+
35+
func FormatVirtualMachineConflictError(vmName string) error {
36+
return fmt.Errorf("VirtualMachine with name %s already exists", vmName)
37+
}
38+
39+
func FormatVirtualDiskConflictError(vdName string) error {
40+
return fmt.Errorf("VirtualDisk with name %s already exists", vdName)
41+
}
42+
43+
func FormatVirtualDiskAttachedError(vdName, attachedVM string) error {
44+
return fmt.Errorf("VirtualDisk with name %s attached to VirtualMachine %s", vdName, attachedVM)
45+
}
46+
47+
func FormatVMBDAConflictError(vmbdaName string) error {
48+
return fmt.Errorf("VirtualMachineBlockDeviceAttachment with name %s already exists", vmbdaName)
49+
}
50+
51+
func FormatVMBDAAttachedError(vmbdaName, attachedVM string) error {
52+
return fmt.Errorf("VirtualMachineBlockDeviceAttachment with name %s already exists and attached to VirtualMachine %s", vmbdaName, attachedVM)
53+
}
54+
55+
func FormatVMIPAttachedError(vmipName, attachedVM string) error {
56+
return fmt.Errorf("VirtualMachineIPAddress with name %s already exists and attached to VirtualMachine %s", vmipName, attachedVM)
57+
}
58+
59+
func FormatImageResourceNotFoundError(resourceType, resourceName, vmName string) error {
60+
return fmt.Errorf("%s %s is used by VirtualMachine %s but absent in cluster", resourceType, resourceName, vmName)
61+
}
62+
63+
func FormatSecretContentDifferentError(secretName string) error {
64+
return fmt.Errorf("content of the secret %s is different from that in the snapshot", secretName)
65+
}

images/virtualization-artifact/pkg/controller/service/restorer/interfaces.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"context"
2121

2222
"sigs.k8s.io/controller-runtime/pkg/client"
23+
24+
"github.com/deckhouse/virtualization/api/core/v1alpha2"
2325
)
2426

2527
//go:generate go tool moq -rm -out mock.go . ObjectHandler
@@ -29,4 +31,5 @@ type ObjectHandler interface {
2931
ProcessRestore(ctx context.Context) error
3032
ValidateClone(ctx context.Context) error
3133
ProcessClone(ctx context.Context) error
34+
Override(rules []v1alpha2.NameReplacement)
3235
}

0 commit comments

Comments
 (0)