forked from oVirt/go-ovirt-client
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient_template.go
230 lines (199 loc) · 7.31 KB
/
client_template.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
package ovirtclient
import (
ovirtsdk "github.com/ovirt/go-ovirt"
)
//go:generate go run scripts/rest.go -i "Template" -n "template" -T "TemplateID"
// TemplateClient represents the portion of the client that deals with VM templates.
type TemplateClient interface {
// CreateTemplate creates a new template from an existing VM.
CreateTemplate(vmID string, name string, params OptionalTemplateCreateParameters, retries ...RetryStrategy) (
Template,
error,
)
// ListTemplates returns all templates stored in the oVirt engine.
ListTemplates(retries ...RetryStrategy) ([]Template, error)
// GetTemplate returns a template by its ID.
GetTemplate(id TemplateID, retries ...RetryStrategy) (Template, error)
// GetBlankTemplate finds a blank template in the oVirt engine and returns it. If no blank template is present,
// this function will return an error.
GetBlankTemplate(retries ...RetryStrategy) (Template, error)
// RemoveTemplate removes the template with the specified ID.
RemoveTemplate(templateID TemplateID, retries ...RetryStrategy) error
// WaitForTemplateStatus waits for a template to enter a specific status.
WaitForTemplateStatus(templateID TemplateID, status TemplateStatus, retries ...RetryStrategy) (Template, error)
// CopyTemplateDiskToStorageDomain copies template disk to the specified storage domain.
CopyTemplateDiskToStorageDomain(diskID string, storageDomainID string, retries ...RetryStrategy) (Disk, error)
}
// TemplateID is an identifier for a template. It has a special type so the compiler
// can catch errors when the template ID is erroneously passed elsewhere.
type TemplateID string
// TemplateData is a set of prepared configurations for VMs.
type TemplateData interface {
// ID returns the identifier of the template. This is typically a UUID.
ID() TemplateID
// Name is the human-readable name for the template.
Name() string
// Description is a longer description for the template.
Description() string
// Status returns the status of the template.
Status() TemplateStatus
// CPU returns the CPU configuration of the template if any.
CPU() VMCPU
// IsBlank returns true, if the template either has the ID of all zeroes, or if the template has no settings, disks,
// or other settings. This function only checks the details supported by go-ovirt-client.
IsBlank() bool
}
// Template incorporates the TemplateData to provide access to data in a template, but also
// adds convenience functions to work with templates.
type Template interface {
TemplateData
// WaitForStatus waits for a template to enter a specific status. It returns the updated
// template as a result.
WaitForStatus(status TemplateStatus, retries ...RetryStrategy) (Template, error)
// ListDiskAttachments lists all disk attachments for the current template.
ListDiskAttachments(retries ...RetryStrategy) ([]TemplateDiskAttachment, error)
// Remove removes the specified template.
Remove(retries ...RetryStrategy) error
}
// TemplateStatus represents the status the template is in.
type TemplateStatus string
const (
// TemplateStatusOK indicates that the template is ready and can be used.
TemplateStatusOK TemplateStatus = "ok"
// TemplateStatusLocked means that an operation is taking place on the template and cannot
// be currently modified.
TemplateStatusLocked TemplateStatus = "locked"
// TemplateStatusIllegal indicates that the template is invalid and cannot be used.
TemplateStatusIllegal TemplateStatus = "illegal"
)
// OptionalTemplateCreateParameters contains the optional parameters for creating a template.
type OptionalTemplateCreateParameters interface {
Description() *string
}
// BuildableTemplateCreateParameters is a buildable version of OptionalTemplateCreateParameters.
type BuildableTemplateCreateParameters interface {
OptionalTemplateCreateParameters
// WithDescription sets the description of a template.
WithDescription(description string) (BuildableTemplateCreateParameters, error)
// MustWithDescription is identical to WithDescription, but panics instead of returning an error.
MustWithDescription(description string) BuildableTemplateCreateParameters
}
type templateCreateParameters struct {
description *string
}
func (t templateCreateParameters) Description() *string {
return t.description
}
func (t templateCreateParameters) WithDescription(description string) (BuildableTemplateCreateParameters, error) {
t.description = &description
return t, nil
}
func (t templateCreateParameters) MustWithDescription(description string) BuildableTemplateCreateParameters {
builder, err := t.WithDescription(description)
if err != nil {
panic(err)
}
return builder
}
// TemplateCreateParams creates a builder for the parameters of the template creation.
func TemplateCreateParams() BuildableTemplateCreateParameters {
return &templateCreateParameters{}
}
func convertSDKTemplate(sdkTemplate *ovirtsdk.Template, client Client) (Template, error) {
id, ok := sdkTemplate.Id()
if !ok {
return nil, newError(EFieldMissing, "template does not contain ID")
}
name, ok := sdkTemplate.Name()
if !ok {
return nil, newError(EFieldMissing, "template does not contain a name")
}
description, ok := sdkTemplate.Description()
if !ok {
return nil, newError(EFieldMissing, "template does not contain a description")
}
status, ok := sdkTemplate.Status()
if !ok {
return nil, newFieldNotFound("template", "status")
}
cpu, err := convertSDKTemplateCPU(sdkTemplate)
if err != nil {
return nil, err
}
return &template{
client: client,
id: TemplateID(id),
name: name,
status: TemplateStatus(status),
description: description,
cpu: cpu,
}, nil
}
func convertSDKTemplateCPU(sdkObject *ovirtsdk.Template) (*vmCPU, error) {
sdkCPU, ok := sdkObject.Cpu()
if !ok {
return nil, newFieldNotFound("VM", "CPU")
}
cpuTopo, ok := sdkCPU.Topology()
if !ok {
return nil, newFieldNotFound("CPU in VM", "CPU topo")
}
cores, ok := cpuTopo.Cores()
if !ok {
return nil, newFieldNotFound("CPU topo in CPU in VM", "cores")
}
threads, ok := cpuTopo.Threads()
if !ok {
return nil, newFieldNotFound("CPU topo in CPU in VM", "threads")
}
sockets, ok := cpuTopo.Sockets()
if !ok {
return nil, newFieldNotFound("CPU topo in CPU in VM", "sockets")
}
cpu := &vmCPU{
topo: &vmCPUTopo{
uint(cores),
uint(threads),
uint(sockets),
},
}
return cpu, nil
}
type template struct {
client Client
id TemplateID
name string
description string
status TemplateStatus
cpu *vmCPU
}
func (t template) ListDiskAttachments(retries ...RetryStrategy) ([]TemplateDiskAttachment, error) {
return t.client.ListTemplateDiskAttachments(t.id, retries...)
}
func (t template) CPU() VMCPU {
return t.cpu
}
func (t template) Status() TemplateStatus {
return t.status
}
func (t template) WaitForStatus(status TemplateStatus, retries ...RetryStrategy) (Template, error) {
return t.client.WaitForTemplateStatus(t.id, status, retries...)
}
func (t template) Remove(retries ...RetryStrategy) error {
return t.client.RemoveTemplate(t.id, retries...)
}
func (t template) IsBlank() bool {
if t.cpu.topo.sockets != 1 || t.cpu.topo.cores != 1 || t.cpu.topo.threads != 1 {
return false
}
return t.id == DefaultBlankTemplateID
}
func (t template) ID() TemplateID {
return t.id
}
func (t template) Name() string {
return t.name
}
func (t template) Description() string {
return t.description
}