-
-
Notifications
You must be signed in to change notification settings - Fork 160
/
instance.go
374 lines (301 loc) · 11.2 KB
/
instance.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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
package api
import (
"strings"
"time"
)
// GetParentAndSnapshotName returns the parent name, snapshot name, and whether it actually was a snapshot name.
func GetParentAndSnapshotName(name string) (string, string, bool) {
fields := strings.SplitN(name, "/", 2)
if len(fields) == 1 {
return name, "", false
}
return fields[0], fields[1], true
}
// InstanceType represents the type if instance being returned or requested via the API.
type InstanceType string
// InstanceTypeAny defines the instance type value for requesting any instance type.
const InstanceTypeAny = InstanceType("")
// InstanceTypeContainer defines the instance type value for a container.
const InstanceTypeContainer = InstanceType("container")
// InstanceTypeVM defines the instance type value for a virtual-machine.
const InstanceTypeVM = InstanceType("virtual-machine")
// InstancesPost represents the fields available for a new instance.
//
// swagger:model
//
// API extension: instances.
type InstancesPost struct {
InstancePut `yaml:",inline"`
// Instance name
// Example: foo
Name string `json:"name" yaml:"name"`
// Creation source
Source InstanceSource `json:"source" yaml:"source"`
// Cloud instance type (AWS, GCP, Azure, ...) to emulate with limits
// Example: t1.micro
InstanceType string `json:"instance_type" yaml:"instance_type"`
// Type (container or virtual-machine)
// Example: container
Type InstanceType `json:"type" yaml:"type"`
// Whether to start the instance after creation
// Example: true
//
// API extension: instance_create_start
Start bool `json:"start" yaml:"start"`
}
// InstancesPut represents the fields available for a mass update.
//
// swagger:model
//
// API extension: instance_bulk_state_change.
type InstancesPut struct {
// Desired runtime state
State *InstanceStatePut `json:"state" yaml:"state"`
}
// InstancePost represents the fields required to rename/move an instance.
//
// swagger:model
//
// API extension: instances.
type InstancePost struct {
// New name for the instance
// Example: bar
Name string `json:"name" yaml:"name"`
// Whether the instance is being migrated to another server
// Example: false
Migration bool `json:"migration" yaml:"migration"`
// Whether to perform a live migration (migration only)
// Example: false
Live bool `json:"live" yaml:"live"`
// Whether snapshots should be discarded (migration only)
// Example: false
InstanceOnly bool `json:"instance_only" yaml:"instance_only"`
// Target for the migration, will use pull mode if not set (migration only)
Target *InstancePostTarget `json:"target" yaml:"target"`
// Target pool for local cross-pool move
// Example: baz
//
// API extension: instance_pool_move
Pool string `json:"pool" yaml:"pool"`
// Target project for local cross-project move
// Example: foo
//
// API extension: instance_project_move
Project string `json:"project" yaml:"project"`
// AllowInconsistent allow inconsistent copies when migrating.
// Example: false
//
// API extension: instance_allow_inconsistent_copy
AllowInconsistent bool `json:"allow_inconsistent" yaml:"allow_inconsistent"`
// Instance configuration file.
// Example: {"security.nesting": "true"}
//
// API extension: instance_move_config
Config map[string]string
// Instance devices.
// Example: {"root": {"type": "disk", "pool": "default", "path": "/"}}
//
// API extension: instance_move_config
Devices map[string]map[string]string
// List of profiles applied to the instance.
// Example: ["default"]
//
// API extension: instance_move_config
Profiles []string
}
// InstancePostTarget represents the migration target host and operation.
//
// swagger:model
//
// API extension: instances.
type InstancePostTarget struct {
// The certificate of the migration target
// Example: X509 PEM certificate
Certificate string `json:"certificate" yaml:"certificate"`
// The operation URL on the remote target
// Example: https://1.2.3.4:8443/1.0/operations/5e8e1638-5345-4c2d-bac9-2c79c8577292
Operation string `json:"operation,omitempty" yaml:"operation,omitempty"`
// Migration websockets credentials
// Example: {"migration": "random-string", "criu": "random-string"}
Websockets map[string]string `json:"secrets,omitempty" yaml:"secrets,omitempty"`
}
// InstancePut represents the modifiable fields of an instance.
//
// swagger:model
//
// API extension: instances.
type InstancePut struct {
// Architecture name
// Example: x86_64
Architecture string `json:"architecture" yaml:"architecture"`
// Instance configuration (see doc/instances.md)
// Example: {"security.nesting": "true"}
Config map[string]string `json:"config" yaml:"config"`
// Instance devices (see doc/instances.md)
// Example: {"root": {"type": "disk", "pool": "default", "path": "/"}}
Devices map[string]map[string]string `json:"devices" yaml:"devices"`
// Whether the instance is ephemeral (deleted on shutdown)
// Example: false
Ephemeral bool `json:"ephemeral" yaml:"ephemeral"`
// List of profiles applied to the instance
// Example: ["default"]
Profiles []string `json:"profiles" yaml:"profiles"`
// If set, instance will be restored to the provided snapshot name
// Example: snap0
Restore string `json:"restore,omitempty" yaml:"restore,omitempty"`
// Whether the instance currently has saved state on disk
// Example: false
Stateful bool `json:"stateful" yaml:"stateful"`
// Instance description
// Example: My test instance
Description string `json:"description" yaml:"description"`
}
// InstanceRebuildPost indicates how to rebuild an instance.
//
// swagger:model
//
// API extension: instances_rebuild.
type InstanceRebuildPost struct {
// Rebuild source
Source InstanceSource `json:"source" yaml:"source"`
}
// Instance represents an instance.
//
// swagger:model
//
// API extension: instances.
type Instance struct {
InstancePut `yaml:",inline"`
// Instance creation timestamp
// Example: 2021-03-23T20:00:00-04:00
CreatedAt time.Time `json:"created_at" yaml:"created_at"`
// Expanded configuration (all profiles and local config merged)
// Example: {"security.nesting": "true"}
ExpandedConfig map[string]string `json:"expanded_config,omitempty" yaml:"expanded_config,omitempty"`
// Expanded devices (all profiles and local devices merged)
// Example: {"root": {"type": "disk", "pool": "default", "path": "/"}}
ExpandedDevices map[string]map[string]string `json:"expanded_devices,omitempty" yaml:"expanded_devices,omitempty"`
// Instance name
// Example: foo
Name string `json:"name" yaml:"name"`
// Instance status (see instance_state)
// Example: Running
Status string `json:"status" yaml:"status"`
// Instance status code (see instance_state)
// Example: 101
StatusCode StatusCode `json:"status_code" yaml:"status_code"`
// Last start timestamp
// Example: 2021-03-23T20:00:00-04:00
LastUsedAt time.Time `json:"last_used_at" yaml:"last_used_at"`
// What cluster member this instance is located on
// Example: server01
Location string `json:"location" yaml:"location"`
// The type of instance (container or virtual-machine)
// Example: container
Type string `json:"type" yaml:"type"`
// Instance project name
// Example: foo
//
// API extension: instance_all_projects
Project string `json:"project" yaml:"project"`
}
// InstanceFull is a combination of Instance, InstanceBackup, InstanceState and InstanceSnapshot.
//
// swagger:model
//
// API extension: instances.
type InstanceFull struct {
Instance `yaml:",inline"`
// List of backups.
Backups []InstanceBackup `json:"backups" yaml:"backups"`
// Current state.
State *InstanceState `json:"state" yaml:"state"`
// List of snapshots.
Snapshots []InstanceSnapshot `json:"snapshots" yaml:"snapshots"`
}
// Writable converts a full Instance struct into a InstancePut struct (filters read-only fields).
//
// API extension: instances.
func (c *Instance) Writable() InstancePut {
return c.InstancePut
}
// IsActive checks whether the instance state indicates the instance is active.
//
// API extension: instances.
func (c Instance) IsActive() bool {
switch c.StatusCode {
case Stopped:
return false
case Error:
return false
default:
return true
}
}
// URL returns the URL for the instance.
func (c *Instance) URL(apiVersion string, project string) *URL {
return NewURL().Path(apiVersion, "instances", c.Name).Project(project)
}
// InstanceSource represents the creation source for a new instance.
//
// swagger:model
//
// API extension: instances.
type InstanceSource struct {
// Source type
// Example: image
Type string `json:"type" yaml:"type"`
// Certificate (for remote images or migration)
// Example: X509 PEM certificate
Certificate string `json:"certificate" yaml:"certificate"`
// Image alias name (for image source)
// Example: ubuntu/22.04
Alias string `json:"alias,omitempty" yaml:"alias,omitempty"`
// Image fingerprint (for image source)
// Example: ed56997f7c5b48e8d78986d2467a26109be6fb9f2d92e8c7b08eb8b6cec7629a
Fingerprint string `json:"fingerprint,omitempty" yaml:"fingerprint,omitempty"`
// Image filters (for image source)
// Example: {"os": "Ubuntu", "release": "jammy", "variant": "cloud"}
Properties map[string]string `json:"properties,omitempty" yaml:"properties,omitempty"`
// Remote server URL (for remote images)
// Example: https://images.linuxcontainers.org
Server string `json:"server,omitempty" yaml:"server,omitempty"`
// Remote server secret (for remote private images)
// Example: RANDOM-STRING
Secret string `json:"secret,omitempty" yaml:"secret,omitempty"`
// Protocol name (for remote image)
// Example: simplestreams
Protocol string `json:"protocol,omitempty" yaml:"protocol,omitempty"`
// Base image fingerprint (for faster migration)
// Example: ed56997f7c5b48e8d78986d2467a26109be6fb9f2d92e8c7b08eb8b6cec7629a
BaseImage string `json:"base-image,omitempty" yaml:"base-image,omitempty"`
// Whether to use pull or push mode (for migration)
// Example: pull
Mode string `json:"mode,omitempty" yaml:"mode,omitempty"`
// Remote operation URL (for migration)
// Example: https://1.2.3.4:8443/1.0/operations/1721ae08-b6a8-416a-9614-3f89302466e1
Operation string `json:"operation,omitempty" yaml:"operation,omitempty"`
// Map of migration websockets (for migration)
// Example: {"criu": "RANDOM-STRING", "rsync": "RANDOM-STRING"}
Websockets map[string]string `json:"secrets,omitempty" yaml:"secrets,omitempty"`
// Existing instance name or snapshot (for copy)
// Example: foo/snap0
Source string `json:"source,omitempty" yaml:"source,omitempty"`
// Whether this is a live migration (for migration)
// Example: false
Live bool `json:"live,omitempty" yaml:"live,omitempty"`
// Whether the copy should skip the snapshots (for copy)
// Example: false
InstanceOnly bool `json:"instance_only,omitempty" yaml:"instance_only,omitempty"`
// Whether this is refreshing an existing instance (for migration and copy)
// Example: false
Refresh bool `json:"refresh,omitempty" yaml:"refresh,omitempty"`
// Source project name (for copy and local image)
// Example: blah
Project string `json:"project,omitempty" yaml:"project,omitempty"`
// Whether to ignore errors when copying (e.g. for volatile files)
// Example: false
//
// API extension: instance_allow_inconsistent_copy
AllowInconsistent bool `json:"allow_inconsistent" yaml:"allow_inconsistent"`
}