-
Notifications
You must be signed in to change notification settings - Fork 118
/
Copy pathvolume.go
399 lines (373 loc) · 19.7 KB
/
volume.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
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
package volume
import (
"context"
"errors"
"github.com/libopenstorage/openstorage/api"
)
var (
// ErrAlreadyShutdown returned when driver is shutdown
ErrAlreadyShutdown = errors.New("VolumeDriverProvider already shutdown")
// ErrExit returned when driver already registered
ErrExist = errors.New("Already exists")
// ErrDriverNotFound returned when a driver is not registered
ErrDriverNotFound = errors.New("Driver implementation not found")
// ErrDriverInitializing returned when a driver is initializing
ErrDriverInitializing = errors.New("Driver is initializing")
// ErrEnoEnt returned when volume does not exist
ErrEnoEnt = errors.New("Volume does not exist.")
// ErrEnomem returned when we are out of memory
ErrEnomem = errors.New("Out of memory.")
// ErrEinval returned when an invalid input is provided
ErrEinval = errors.New("Invalid argument")
// ErrVolDetached returned when volume is in detached state
ErrVolDetached = errors.New("Volume is detached")
// ErrAttachedHostSpecNotFound returned when the attached host's spec is not found
ErrAttachedHostSpecNotFound = errors.New("Spec of the attached host is not found")
// ErrVolAttached returned when volume is in attached state
ErrVolAttached = errors.New("Volume is attached")
// ErrVolAttachedOnRemoteNode returned when volume is attached on different node
ErrVolAttachedOnRemoteNode = errors.New("Volume is attached on another node")
// ErrNonSharedVolAttachedOnRemoteNode returned when a non-shared volume is attached on different node
ErrNonSharedVolAttachedOnRemoteNode = errors.New("Non-shared volume is already attached on another node." +
" Non-shared volumes can only be attached on one node at a time.")
// ErrVolAttachedScale returned when volume is attached and can be scaled
ErrVolAttachedScale = errors.New("Volume is attached on another node." +
" Increase scale factor to create more instances")
// ErrVolHasSnaps returned when volume has previous snapshots
ErrVolHasSnaps = errors.New("Volume has snapshots associated")
// ErrNotSupported returned when the operation is not supported
ErrNotSupported = errors.New("Operation not supported")
// ErrVolBusy returned when volume is in busy state
ErrVolBusy = errors.New("Volume is busy")
// ErrAborted returned when capacityUsageInfo cannot be returned
ErrAborted = errors.New("Aborted CapacityUsage request")
// ErrInvalidName returned when Cloudbackup Name/request is invalid
ErrInvalidName = errors.New("Invalid name for cloud backup/restore request")
// ErrFsResizeFailed returned when Filesystem resize failed because of filesystem
// errors
ErrFsResizeFailed = errors.New("Filesystem Resize failed due to filesystem errors")
// ErrNoVolumeUpdate is returned when a volume update has no changes requested
ErrNoVolumeUpdate = errors.New("No change requested")
)
// Constants used by the VolumeDriver
const (
// APIVersion for the volume management apis
APIVersion = "v1"
// PluginAPIBase where the docker unix socket resides
PluginAPIBase = "/run/docker/plugins/"
// DriverAPIBase where the osd unix socket resides
DriverAPIBase = "/var/lib/osd/driver/"
// MountBase for osd mountpoints
MountBase = "/var/lib/osd/mounts/"
// VolumeBase for osd volumes
VolumeBase = "/var/lib/osd/"
)
const (
// LocationConstaint is a label that specifies data location constraint.
LocationConstraint = "LocationConstraint"
// LocalNode is an alias for this node - similar to localhost.
LocalNode = "LocalNode"
// FromTrashCan is a label that specified a volume being in the TrashCan
FromTrashCan = "FromTrashCan"
)
// Store defines the interface for basic volume store operations
type Store interface {
// Lock volume specified by volumeID.
Lock(volumeID string) (interface{}, error)
// Lock volume with token obtained from call to Lock.
Unlock(token interface{}) error
// CreateVol returns error if volume with the same ID already existe.
CreateVol(vol *api.Volume) error
// GetVol from volumeID.
GetVol(volumeID string) (*api.Volume, error)
// UpdateVol with vol
UpdateVol(vol *api.Volume) error
// DeleteVol. Returns error if volume does not exist.
DeleteVol(volumeID string) error
}
// VolumeDriver is the main interface to be implemented by any storage driver.
// Every driver must at minimum implement the ProtoDriver sub interface.
type VolumeDriver interface {
IODriver
ProtoDriver
BlockDriver
Enumerator
Watcher
}
// IODriver interfaces applicable to object store interfaces.
type IODriver interface {
// Read sz bytes from specified volume at specified offset.
// Return number of bytes read and error.
Read(volumeID string, buf []byte, sz uint64, offset int64) (int64, error)
// Write sz bytes from specified volume at specified offset.
// Return number of bytes written and error.
Write(volumeID string, buf []byte, sz uint64, offset int64) (int64, error)
// Flush writes to stable storage.
// Return error.
Flush(volumeID string) error
}
// SnapshotDriver interfaces provides snapshot capability
type SnapshotDriver interface {
// Snapshot create volume snapshot.
// Errors ErrEnoEnt may be returned
Snapshot(ctx context.Context, volumeID string, readonly bool, locator *api.VolumeLocator, noRetry bool) (string, error)
// Restore restores volume to specified snapshot.
Restore(volumeID string, snapshotID string) error
// SnapshotGroup takes a snapshot of a group of volumes that can be specified with either of the following
// 1. group ID
// 2. labels
// 3. volumeIDs
// deleteOnFailure indicates whether to delete the successful snaps if some of the snapshots failed
SnapshotGroup(groupID string, labels map[string]string, volumeIDs []string, deleteOnFailure bool) (*api.GroupSnapCreateResponse, error)
}
// StatsDriver interface provides stats features
type StatsDriver interface {
// Stats for specified volume.
// cumulative stats are /proc/diskstats style stats.
// nonCumulative stats are stats for specific duration.
// Errors ErrEnoEnt may be returned
Stats(ctx context.Context, volumeID string, cumulative bool) (*api.Stats, error)
// UsedSize returns currently used volume size.
// Errors ErrEnoEnt may be returned.
UsedSize(volumeID string) (uint64, error)
// GetActiveRequests get active requests
GetActiveRequests() (*api.ActiveRequests, error)
// CapacityUsage returns both exclusive and shared usage
// of a snap/volume
CapacityUsage(ID string) (*api.CapacityUsageResponse, error)
// VolumeUsageByNode returns capacity usage of all volumes and snaps for a
// given node
VolumeUsageByNode(ctx context.Context, nodeID string) (*api.VolumeUsageByNode, error)
// RelaxedReclaimPurge triggers the purge of RelaxedReclaim queue for a
// given node
RelaxedReclaimPurge(nodeID string) (*api.RelaxedReclaimPurge, error)
// VolumeBytesUsedByNode returns currently used volume util of multiple volumes
// on a given node
VolumeBytesUsedByNode(nodeID string, ids []uint64) (*api.VolumeBytesUsedByNode, error)
}
type QuiesceDriver interface {
// Freezes mounted filesystem resulting in a quiesced volume state.
// Only one freeze operation may be active at any given time per volume.
// Unfreezes after timeout seconds if it is non-zero.
// An optional quiesceID can be passed for driver-specific use.
Quiesce(volumeID string, timeoutSeconds uint64, quiesceID string) error
// Unfreezes mounted filesystem if it was frozen.
Unquiesce(volumeID string) error
}
// CloudBackupDriver interface provides Cloud backup features
type CloudBackupDriver interface {
// CloudBackupCreate uploads snapshot of a volume to the cloud
CloudBackupCreate(input *api.CloudBackupCreateRequest) (*api.CloudBackupCreateResponse, error)
// CloudBackupGroupCreate creates and then uploads volumegroup snapshots
CloudBackupGroupCreate(input *api.CloudBackupGroupCreateRequest) (*api.CloudBackupGroupCreateResponse, error)
// CloudBackupRestore downloads a cloud backup and restores it to a volume
CloudBackupRestore(input *api.CloudBackupRestoreRequest) (*api.CloudBackupRestoreResponse, error)
// CloudBackupEnumerate enumerates the backups for a given cluster/credential/volumeID
CloudBackupEnumerate(input *api.CloudBackupEnumerateRequest) (*api.CloudBackupEnumerateResponse, error)
// CloudBackupDelete deletes the specified backup in cloud
CloudBackupDelete(input *api.CloudBackupDeleteRequest) error
// CloudBackupDelete deletes all the backups for a given volume in cloud
CloudBackupDeleteAll(input *api.CloudBackupDeleteAllRequest) error
// CloudBackupStatus indicates the most recent status of backup/restores
CloudBackupStatus(input *api.CloudBackupStatusRequest) (*api.CloudBackupStatusResponse, error)
// CloudBackupCatalog displays listing of backup content
CloudBackupCatalog(input *api.CloudBackupCatalogRequest) (*api.CloudBackupCatalogResponse, error)
// CloudBackupHistory displays past backup/restore operations on a volume
CloudBackupHistory(input *api.CloudBackupHistoryRequest) (*api.CloudBackupHistoryResponse, error)
// CloudBackupStateChange allows a current backup state transitions(pause/resume/stop)
CloudBackupStateChange(input *api.CloudBackupStateChangeRequest) error
// CloudBackupSchedCreate creates a schedule to backup volume to cloud
CloudBackupSchedCreate(input *api.CloudBackupSchedCreateRequest) (*api.CloudBackupSchedCreateResponse, error)
// CloudBackupGroupSchedCreate creates a schedule to backup a volumegroup to cloud
CloudBackupGroupSchedCreate(input *api.CloudBackupGroupSchedCreateRequest) (*api.CloudBackupSchedCreateResponse, error)
// CloudBackupSchedCreate creates a schedule to backup volume to cloud
CloudBackupSchedUpdate(input *api.CloudBackupSchedUpdateRequest) error
// CloudBackupGroupSchedCreate creates a schedule to backup a volumegroup to cloud
CloudBackupGroupSchedUpdate(input *api.CloudBackupGroupSchedUpdateRequest) error
// CloudBackupSchedDelete delete a backup schedule
CloudBackupSchedDelete(input *api.CloudBackupSchedDeleteRequest) error
// CloudBackupSchedEnumerate enumerates the configured backup schedules in the cluster
CloudBackupSchedEnumerate() (*api.CloudBackupSchedEnumerateResponse, error)
// CloudBackupSize fetches the size of a cloud backup
CloudBackupSize(input *api.SdkCloudBackupSizeRequest) (*api.SdkCloudBackupSizeResponse, error)
}
// CloudMigrateDriver interface provides Cloud migration features
type CloudMigrateDriver interface {
// CloudMigrateStart starts a migrate operation
CloudMigrateStart(request *api.CloudMigrateStartRequest) (*api.CloudMigrateStartResponse, error)
// CloudMigrateCancel cancels a migrate operation
CloudMigrateCancel(request *api.CloudMigrateCancelRequest) error
// CloudMigrateStatus returns status for the migration operations
CloudMigrateStatus(request *api.CloudMigrateStatusRequest) (*api.CloudMigrateStatusResponse, error)
}
// FilesystemTrimDriver interface exposes APIs to manage filesystem trim
// operation on a volume
type FilesystemTrimDriver interface {
// FilesystemTrimStart starts a filesystem trim background operation on a
// specified volume
FilesystemTrimStart(request *api.SdkFilesystemTrimStartRequest) (*api.SdkFilesystemTrimStartResponse, error)
// FilesystemTrimStatus returns the status of a filesystem trim
// background operation on a specified volume, if any
FilesystemTrimStatus(request *api.SdkFilesystemTrimStatusRequest) (*api.SdkFilesystemTrimStatusResponse, error)
// AutoFilesystemTrimStatus returns the status of auto fs trim
// operations on volumes
AutoFilesystemTrimStatus(request *api.SdkAutoFSTrimStatusRequest) (*api.SdkAutoFSTrimStatusResponse, error)
// AutoFilesystemTrimUsage returns the volume usage and trimmable
// space of locally mounted pxd volumes
AutoFilesystemTrimUsage(request *api.SdkAutoFSTrimUsageRequest) (*api.SdkAutoFSTrimUsageResponse, error)
// FilesystemTrimStop stops a filesystem trim background operation on
// a specified volume, if any
FilesystemTrimStop(request *api.SdkFilesystemTrimStopRequest) (*api.SdkFilesystemTrimStopResponse, error)
// AutoFilesystemTrimPush pushes an autofstrim job to queue
AutoFilesystemTrimPush(request *api.SdkAutoFSTrimPushRequest) (*api.SdkAutoFSTrimPushResponse, error)
// AutoFilesystemTrimPop pops an autofstrim job from queue
AutoFilesystemTrimPop(request *api.SdkAutoFSTrimPopRequest) (*api.SdkAutoFSTrimPopResponse, error)
}
// FilesystemCheckDriver interface exposes APIs to manage filesystem check
// operation on a volume
type FilesystemCheckDriver interface {
// FilesystemCheckStart starts a filesystem check background operation
// on a specified volume
FilesystemCheckStart(request *api.SdkFilesystemCheckStartRequest) (*api.SdkFilesystemCheckStartResponse, error)
// FilesystemCheckStatus returns the status of a filesystem check
// background operation on the filesystem of a specified volume, if any.
FilesystemCheckStatus(request *api.SdkFilesystemCheckStatusRequest) (*api.SdkFilesystemCheckStatusResponse, error)
// FilesystemCheckStop stops the filesystem check background operation on
// the filesystem of a specified volume, if any.
FilesystemCheckStop(request *api.SdkFilesystemCheckStopRequest) (*api.SdkFilesystemCheckStopResponse, error)
// FilesystemCheckListSnapshots lists snapshots created by fsck for a specified volume
FilesystemCheckListSnapshots(request *api.SdkFilesystemCheckListSnapshotsRequest) (*api.SdkFilesystemCheckListSnapshotsResponse, error)
// FilesystemCheckDeleteSnapshots deletes snapshots created by fsck for a specified volume
FilesystemCheckDeleteSnapshots(request *api.SdkFilesystemCheckDeleteSnapshotsRequest) (*api.SdkFilesystemCheckDeleteSnapshotsResponse, error)
// FilesystemCheckListVolumes lists volumes that require fsck check/fixes
FilesystemCheckListVolumes(request *api.SdkFilesystemCheckListVolumesRequest) (*api.SdkFilesystemCheckListVolumesResponse, error)
}
// ProtoDriver must be implemented by all volume drivers. It specifies the
// most basic functionality, such as creating and deleting volumes.
type ProtoDriver interface {
SnapshotDriver
StatsDriver
QuiesceDriver
CredsDriver
CloudBackupDriver
CloudMigrateDriver
FilesystemTrimDriver
FilesystemCheckDriver
VerifyChecksumDriver
// Name returns the name of the driver.
Name() string
// Type of this driver
Type() api.DriverType
// Version information of the driver
Version() (*api.StorageVersion, error)
// Create a new Vol for the specific volume spec.
// It returns a system generated VolumeID that uniquely identifies the volume
Create(ctx context.Context, locator *api.VolumeLocator, Source *api.Source, spec *api.VolumeSpec) (string, error)
// Delete volume.
// Errors ErrEnoEnt, ErrVolHasSnaps may be returned.
Delete(ctx context.Context, volumeID string) error
// Mount volume at specified path
// Errors ErrEnoEnt, ErrVolDetached may be returned.
Mount(ctx context.Context, volumeID string, mountPath string, options map[string]string) error
// MountedAt return volume mounted at specified mountpath.
MountedAt(ctx context.Context, mountPath string) string
// Unmount volume at specified path
// Errors ErrEnoEnt, ErrVolDetached may be returned.
Unmount(ctx context.Context, volumeID string, mountPath string, options map[string]string) error
// Update not all fields of the spec are supported, ErrNotSupported will be thrown for unsupported
// updates.
Set(ctx context.Context, volumeID string, locator *api.VolumeLocator, spec *api.VolumeSpec) error
// Status returns a set of key-value pairs which give low
// level diagnostic status about this driver.
Status() [][2]string
// Shutdown and cleanup.
Shutdown()
// DU specified volume and potentially the subfolder if provided.
Catalog(volumeid, subfolder string, depth string) (api.CatalogResponse, error)
// Does a Filesystem Trim operation to free unused space to block device(block discard)
VolService(volumeID string, vsreq *api.VolumeServiceRequest) (*api.VolumeServiceResponse, error)
}
// Enumerator provides a set of interfaces to get details on a set of volumes.
type Enumerator interface {
// Inspect specified volumes.
// Returns slice of volumes that were found.
Inspect(ctx context.Context, volumeIDs []string) ([]*api.Volume, error)
// Enumerate volumes that map to the volumeLocator. Locator fields may be regexp.
// If locator fields are left blank, this will return all volumes.
Enumerate(locator *api.VolumeLocator, labels map[string]string) ([]*api.Volume, error)
// Enumerate snaps for specified volumes
SnapEnumerate(volID []string, snapLabels map[string]string) ([]*api.Volume, error)
}
// Water provides a set of function to get volume
type Watcher interface {
// Stop Volume notifier
StartVolumeWatcher()
// Gets Volume notifier
GetVolumeWatcher(locator *api.VolumeLocator, labels map[string]string) (chan *api.Volume, error)
// Stop Volume notifier
StopVolumeWatcher()
}
// StoreEnumerator combines Store and Enumerator capabilities
type StoreEnumerator interface {
Store
Enumerator
}
// BlockDriver needs to be implemented by block volume drivers. Filesystem volume
// drivers can ignore this interface and include the builtin DefaultBlockDriver.
type BlockDriver interface {
// Attach map device to the host.
// On success the devicePath specifies location where the device is exported
// Errors ErrEnoEnt, ErrVolAttached may be returned.
Attach(ctx context.Context, volumeID string, attachOptions map[string]string) (string, error)
// Detach device from the host.
// Errors ErrEnoEnt, ErrVolDetached may be returned.
Detach(ctx context.Context, volumeID string, options map[string]string) error
}
// CredsDriver provides methods to handle credentials
type CredsDriver interface {
// CredsCreate creates credential for a given cloud provider
CredsCreate(params map[string]string) (string, error)
// CredsUpdate updates credential for an already configured credential
CredsUpdate(name string, params map[string]string) error
// CredsEnumerate lists the configured credentials in the cluster
CredsEnumerate() (map[string]interface{}, error)
// CredsDelete deletes the credential associated credUUID
CredsDelete(credUUID string) error
// CredsValidate validates the credential associated credUUID
CredsValidate(credUUID string) error
// CredsDeleteReferences delets any with the creds
CredsDeleteReferences(credUUID string) error
}
// VolumeDriverProvider provides VolumeDrivers.
type VolumeDriverProvider interface {
// Get gets the VolumeDriver for the given name.
// If a VolumeDriver was not created for the given name, the error ErrDriverNotFound is returned.
Get(name string) (VolumeDriver, error)
// Shutdown shuts down all volume drivers.
Shutdown() error
}
// VolumeDriverRegistry registers VolumeDrivers.
type VolumeDriverRegistry interface {
VolumeDriverProvider
// New creates the VolumeDriver for the given name.
// If a VolumeDriver was already created for the given name, the error ErrExist is returned.
Register(name string, params map[string]string) error
// Add inserts a new VolumeDriver provider with a well known name.
Add(name string, init func(map[string]string) (VolumeDriver, error)) error
// Removes driver from registry. Does nothing if driver name does not exist.
Remove(name string)
}
// VerifyChecksumDriver interface exposes APIs to manage checksum validation
// on a volume
type VerifyChecksumDriver interface {
// VerifyChecksumStart starts a checksum validation on a specified volume
VerifyChecksumStart(request *api.SdkVerifyChecksumStartRequest) (*api.SdkVerifyChecksumStartResponse, error)
// VerifyChecksumStatus returns the status of checksum validation task
VerifyChecksumStatus(request *api.SdkVerifyChecksumStatusRequest) (*api.SdkVerifyChecksumStatusResponse, error)
// VerifyChecksumStop stops the checksum validation task
VerifyChecksumStop(request *api.SdkVerifyChecksumStopRequest) (*api.SdkVerifyChecksumStopResponse, error)
}
// NewVolumeDriverRegistry constructs a new VolumeDriverRegistry.
func NewVolumeDriverRegistry(nameToInitFunc map[string]func(map[string]string) (VolumeDriver, error)) VolumeDriverRegistry {
return newVolumeDriverRegistry(nameToInitFunc)
}