forked from longhorn/backupstore
-
Notifications
You must be signed in to change notification settings - Fork 0
/
backupstore.go
133 lines (111 loc) · 3.26 KB
/
backupstore.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
package backupstore
import (
"fmt"
"net/url"
"github.com/longhorn/backupstore/util"
)
type Volume struct {
Name string
Size int64 `json:",string"`
CreatedTime string
LastBackupName string
LastBackupAt string
BlockCount int64 `json:",string"`
}
type Snapshot struct {
Name string
CreatedTime string
}
type Backup struct {
Name string
VolumeName string
SnapshotName string
SnapshotCreatedAt string
CreatedTime string
Size int64 `json:",string"`
Labels map[string]string
IsIncremental bool
Blocks []BlockMapping `json:",omitempty"`
SingleFile BackupFile `json:",omitempty"`
}
var (
backupstoreBase = "backupstore"
)
func SetBackupstoreBase(base string) {
backupstoreBase = base
}
func GetBackupstoreBase() string {
return backupstoreBase
}
func addVolume(volume *Volume, driver BackupStoreDriver) error {
if volumeExists(volume.Name, driver) {
return nil
}
if !util.ValidateName(volume.Name) {
return fmt.Errorf("Invalid volume name %v", volume.Name)
}
if err := saveVolume(volume, driver); err != nil {
log.Error("Fail add volume ", volume.Name)
return err
}
log.Debug("Added backupstore volume ", volume.Name)
return nil
}
func removeVolume(volumeName string, driver BackupStoreDriver) error {
if !util.ValidateName(volumeName) {
return fmt.Errorf("Invalid volume name %v", volumeName)
}
volumeDir := getVolumePath(volumeName)
volumeBlocksDirectory := getBlockPath(volumeName)
volumeBackupsDirectory := getBackupPath(volumeName)
if err := driver.Remove(volumeBackupsDirectory); err != nil {
return fmt.Errorf("failed to remove all the backups for volume %v: %v", volumeName, err)
}
if err := driver.Remove(volumeBlocksDirectory); err != nil {
return fmt.Errorf("failed to remove all the blocks for volume %v: %v", volumeName, err)
}
if err := driver.Remove(volumeDir); err != nil {
return fmt.Errorf("failed to remove backup volume %v directory in backupstore: %v", volumeName, err)
}
log.Debug("Removed volume directory in backupstore: ", volumeDir)
log.Debug("Removed backupstore volume ", volumeName)
return nil
}
func encodeBackupURL(backupName, volumeName, destURL string) string {
v := url.Values{}
v.Add("volume", volumeName)
v.Add("backup", backupName)
return destURL + "?" + v.Encode()
}
func decodeBackupURL(backupURL string) (string, string, error) {
u, err := url.Parse(backupURL)
if err != nil {
return "", "", err
}
v := u.Query()
volumeName := v.Get("volume")
backupName := v.Get("backup")
if !util.ValidateName(volumeName) || !util.ValidateName(backupName) {
return "", "", fmt.Errorf("Invalid name parsed, got %v and %v", backupName, volumeName)
}
return backupName, volumeName, nil
}
func LoadVolume(backupURL string) (*Volume, error) {
_, volumeName, err := decodeBackupURL(backupURL)
if err != nil {
return nil, err
}
driver, err := GetBackupStoreDriver(backupURL)
if err != nil {
return nil, err
}
return loadVolume(volumeName, driver)
}
func GetBackupFromBackupURL(backupURL string) (string, error) {
backup, _, err := decodeBackupURL(backupURL)
return backup, err
}
func GetVolumeFromBackupURL(backupURL string) (string, error) {
_, volume, err := decodeBackupURL(backupURL)
return volume, err
}