This repository has been archived by the owner on Sep 2, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
logical_volume.go
167 lines (141 loc) · 3.87 KB
/
logical_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
package main
import (
"fmt"
"strings"
)
// LogicalVolume defines the LV part of the LVM subsystem pieces.
// This contains the actual or configuration desired.
type LogicalVolume struct {
Name string `json:"name,omitempty"`
Size string `json:"size,omitempty"`
UUID string `json:"uuid,omitempty"`
Path string `json:"path,omitempty"`
// Image defines the image to dd into this disk
Image *Image `json:"image,omitempty"`
// FileSystem defines the file system that should be on this LV.
FileSystem *FileSystem `json:"fs,omitempty"`
imageApplied bool
parentVg string
}
// LogicalVolumes defines a list of LogicalVolume
type LogicalVolumes []*LogicalVolume
// toCompList converts a list of LogicalVolume into a list of Comparator
func (lvs LogicalVolumes) toCompList() []Comparator {
ns := []Comparator{}
for _, lv := range lvs {
ns = append(ns, lv)
}
return ns
}
// ToLogicalVolumeList converts a list of Comparator into a list of LogicalVolume
func ToLogicalVolumeList(src []Comparator, err error) (LogicalVolumes, error) {
if err != nil {
return nil, err
}
lvs := LogicalVolumes{}
for _, s := range src {
lvs = append(lvs, s.(*LogicalVolume))
}
return lvs, nil
}
// updateBlkInfo builds info about the logical volume and fs from lsblk
func (lv *LogicalVolume) updateBlkInfo(keys map[string]string) error {
if fst, ok := keys["FSTYPE"]; ok && fst != "" {
if lv.FileSystem == nil {
lv.FileSystem = &FileSystem{parentPath: lv.Path}
}
fs := lv.FileSystem
fs.updateBlkInfo(keys)
}
return nil
}
// Equal tests identity equivalence
func (lv *LogicalVolume) Equal(c Comparator) bool {
nlv := c.(*LogicalVolume)
return lv.Name == nlv.Name
}
// Merge merges the comparator into the actual object
func (lv *LogicalVolume) Merge(c Comparator) error {
nlv := c.(*LogicalVolume)
lv.Size = nlv.Size
if lv.FileSystem != nil {
if err := lv.FileSystem.Merge(nlv.FileSystem); err != nil {
return err
}
} else {
lv.FileSystem = nlv.FileSystem
}
return nil
}
//
// Validate an Image object.
//
func (lv *LogicalVolume) Validate() error {
out := []string{}
if lv.Name == "" {
out = append(out, "LV must have a name")
}
if lv.Size == "" {
out = append(out, fmt.Sprintf("LV %s must have a size", lv.Name))
}
if lv.Image != nil {
lv.Image.rawOnly = true
if e := lv.Image.Validate(); e != nil {
out = append(out, fmt.Sprintf("lv %s: Image is invalid: %v", lv.Name, e))
}
}
if lv.FileSystem != nil {
e := lv.FileSystem.Validate()
if e != nil {
out = append(out, fmt.Sprintf("lv %s filesystem failed validation: %v", lv.Name, e))
}
}
if len(out) > 0 {
return fmt.Errorf(strings.Join(out, "n"))
}
return nil
}
// Action applies the configuration object to the actual object.
func (lv *LogicalVolume) Action(nlv *LogicalVolume) (Result, error) {
dmsg(DbgAction|DbgLv, "Logical Volume Action %v %v\n", lv, nlv)
if lv.Name == "" {
args := []string{}
args = append(args, "-n", nlv.Name)
if nlv.Size == "REST" {
args = append(args, "-l", "100%FREE")
} else {
args = append(args, "-L", nlv.Size)
}
args = append(args, lv.parentVg)
if _, err := runCommand("lvcreate", args...); err != nil {
return ResultFailed, err
}
return ResultRescan, nil
}
// GREG: validate something.
// Image the logical volume.
if nlv.Image != nil && !lv.imageApplied {
lv.imageApplied = true
// Put image in place
nlv.Image.Path = lv.Path
if err := nlv.Image.Action(); err != nil {
return ResultFailed, err
}
return ResultRescan, nil
}
// Make filesystem if one is here.
if nlv.FileSystem != nil {
// Create it if missing.
rescan := false
if lv.FileSystem == nil {
lv.FileSystem = &FileSystem{parentPath: lv.Path}
rescan = true
}
if rs, err := lv.FileSystem.Action(nlv.FileSystem); err != nil {
return ResultFailed, err
} else if rescan || rs == ResultRescan {
return ResultRescan, nil
}
}
return ResultSuccess, nil
}