/
cloudsnap.go
127 lines (108 loc) · 3.59 KB
/
cloudsnap.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
package snapshot
import (
"fmt"
"github.com/libopenstorage/openstorage/api"
"github.com/libopenstorage/openstorage/volume"
"github.com/sirupsen/logrus"
)
const (
configCred = "credId"
)
type cloudSnapshotPlugin struct {
Plugin
log logrus.FieldLogger
credID string
}
func (c *cloudSnapshotPlugin) Init(config map[string]string) error {
c.credID = config[configCred]
c.log.Infof("Init'ing portworx cloud snapshot with credID %v", c.credID)
return nil
}
func (c *cloudSnapshotPlugin) CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ string, iops *int64) (string, error) {
volDriver, err := getVolumeDriver()
if err != nil {
return "", err
}
// Enumerating can be expensive but we need to do it to get the original
// volume name. Ark already has it so it can pass it down to us.
// CloudBackupRestore can also be updated to restore to the original volume
// name.
enumRequest := &api.CloudBackupEnumerateRequest{}
enumRequest.CredentialUUID = c.credID
enumRequest.All = true
enumResponse, err := volDriver.CloudBackupEnumerate(enumRequest)
if err != nil {
return "", err
}
volumeName := ""
for _, backup := range enumResponse.Backups {
if backup.ID == snapshotID {
volumeName = backup.SrcVolumeName
break
}
}
if volumeName == "" {
c.log.Infof("Error finding volume name for cloudsnap %v", snapshotID)
return "", fmt.Errorf("Couldn't find volume name from cloudsnap")
}
response, err := volDriver.CloudBackupRestore(&api.CloudBackupRestoreRequest{
ID: snapshotID,
CredentialUUID: c.credID,
RestoreVolumeName: volumeName,
})
if err != nil {
c.log.Infof("Error starting cloudsnap restore for %v to %v", snapshotID, volumeName)
return "", err
}
c.log.Infof("Started cloud snapshot restore %v to volume %v", snapshotID, response.RestoreVolumeID)
err = volume.CloudBackupWaitForCompletion(volDriver, response.Name,
api.CloudRestoreOp)
if err != nil {
c.log.Errorf("Error restoring %v to volume %v: %v", snapshotID, response.RestoreVolumeID, err)
return "", err
}
c.log.Infof("Finished cloud snapshot restore %v for %v to volume %v", response.Name, snapshotID, response.RestoreVolumeID)
return response.RestoreVolumeID, nil
}
func (c *cloudSnapshotPlugin) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, error) {
return "portworx-cloudsnapshot", nil, nil
}
func (c *cloudSnapshotPlugin) CreateSnapshot(volumeID, volumeAZ string, tags map[string]string) (string, error) {
volDriver, err := getVolumeDriver()
if err != nil {
return "", err
}
createResp, err := volDriver.CloudBackupCreate(&api.CloudBackupCreateRequest{
VolumeID: volumeID,
Full: true,
CredentialUUID: c.credID,
})
if err != nil {
return "", err
}
c.log.Infof("Started cloud snapshot backup %v for %v", createResp.Name, volumeID)
err = volume.CloudBackupWaitForCompletion(volDriver, createResp.Name, api.CloudBackupOp)
if err != nil {
c.log.Errorf("Error backing up volume %v: %v", volumeID, err)
return "", err
}
statusResponse, err := volDriver.CloudBackupStatus(&api.CloudBackupStatusRequest{
ID: createResp.Name,
})
if err != nil {
return "", err
}
c.log.Infof("Finished cloud snapshot backup %v for %v to %v", createResp.Name, volumeID, statusResponse.Statuses[createResp.Name].ID)
return statusResponse.Statuses[createResp.Name].ID, nil
}
func (c *cloudSnapshotPlugin) DeleteSnapshot(snapshotID string) error {
volDriver, err := getVolumeDriver()
if err != nil {
return err
}
return volDriver.CloudBackupDelete(&api.CloudBackupDeleteRequest{
ID: snapshotID,
CredentialUUID: c.credID,
Force: false,
})
}