Skip to content

Commit ece51c5

Browse files
feat(provision): add support for thin provision lvm volumes (#30)
Signed-off-by: prateekpandey14 <[email protected]>
1 parent 2fa712d commit ece51c5

File tree

8 files changed

+86
-11
lines changed

8 files changed

+86
-11
lines changed

deploy/lvm-operator.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,15 @@ spec:
109109
- "yes"
110110
- "no"
111111
type: string
112+
thinProvision:
113+
description: ThinProvision specifies whether logical volumes can be
114+
thinly provisioned. If it is set to "yes", then the LVM LocalPV
115+
Driver will create thinProvision i.e. logical volumes that are larger
116+
than the available extents.
117+
enum:
118+
- "yes"
119+
- "no"
120+
type: string
112121
volGroup:
113122
description: VolGroup specifies the name of the volume group where
114123
the volume has been created.
@@ -226,6 +235,15 @@ spec:
226235
- "yes"
227236
- "no"
228237
type: string
238+
thinProvision:
239+
description: ThinProvision specifies whether logical volumes can be
240+
thinly provisioned. If it is set to "yes", then the LVM LocalPV
241+
Driver will create thinProvision i.e. logical volumes that are larger
242+
than the available extents.
243+
enum:
244+
- "yes"
245+
- "no"
246+
type: string
229247
volGroup:
230248
description: VolGroup specifies the name of the volume group where
231249
the volume has been created.

deploy/yamls/lvmsnapshot-crd.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ spec:
6565
- "yes"
6666
- "no"
6767
type: string
68+
thinProvision:
69+
description: ThinProvision specifies whether logical volumes can be
70+
thinly provisioned. If it is set to "yes", then the LVM LocalPV
71+
Driver will create thinProvision i.e. logical volumes that are larger
72+
than the available extents.
73+
enum:
74+
- "yes"
75+
- "no"
76+
type: string
6877
volGroup:
6978
description: VolGroup specifies the name of the volume group where
7079
the volume has been created.

deploy/yamls/lvmvolume-crd.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,15 @@ spec:
8888
- "yes"
8989
- "no"
9090
type: string
91+
thinProvision:
92+
description: ThinProvision specifies whether logical volumes can be
93+
thinly provisioned. If it is set to "yes", then the LVM LocalPV
94+
Driver will create thinProvision i.e. logical volumes that are larger
95+
than the available extents.
96+
enum:
97+
- "yes"
98+
- "no"
99+
type: string
91100
volGroup:
92101
description: VolGroup specifies the name of the volume group where
93102
the volume has been created.

pkg/apis/openebs.io/lvm/v1alpha1/lvmvolume.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ type VolumeInfo struct {
7676
// +kubebuilder:validation:Required
7777
// +kubebuilder:validation:Enum=yes;no
7878
Shared string `json:"shared,omitempty"`
79+
80+
// ThinProvision specifies whether logical volumes can be thinly provisioned.
81+
// If it is set to "yes", then the LVM LocalPV Driver will create
82+
// thinProvision i.e. logical volumes that are larger than the available extents.
83+
// +kubebuilder:validation:Required
84+
// +kubebuilder:validation:Enum=yes;no
85+
ThinProvision string `json:"thinProvision,omitempty"`
7986
}
8087

8188
// VolStatus string that specifies the current state of the volume provisioning request.

pkg/builder/volbuilder/volume.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ func (b *Builder) WithShared(shared string) *Builder {
133133
return b
134134
}
135135

136+
// WithThinProvision sets where thinProvision is enable or not
137+
func (b *Builder) WithThinProvision(thinProvision string) *Builder {
138+
b.volume.Object.Spec.ThinProvision = thinProvision
139+
return b
140+
}
141+
136142
// WithVolGroup sets volume group name for creating volume
137143
func (b *Builder) WithVolGroup(vg string) *Builder {
138144
if vg == "" {

pkg/driver/controller.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,8 @@ func CreateLVMVolume(ctx context.Context, req *csi.CreateVolumeRequest,
271271
WithVolGroup(params.VolumeGroup).
272272
WithOwnerNode(owner).
273273
WithVolumeStatus(lvm.LVMStatusPending).
274-
WithShared(params.Shared).Build()
274+
WithShared(params.Shared).
275+
WithThinProvision(params.ThinProvision).Build()
275276

276277
if err != nil {
277278
return nil, status.Error(codes.Internal, err.Error())

pkg/driver/params.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ type VolumeParams struct {
2727
// provisioning logical volumes.
2828
VolumeGroup string
2929

30-
Scheduler string
31-
Shared string
32-
30+
Scheduler string
31+
Shared string
32+
ThinProvision string
3333
// extra optional metadata passed by external provisioner
3434
// if enabled. See --extra-create-metadata flag for more details.
3535
// https://github.com/kubernetes-csi/external-provisioner#recommended-optional-arguments
@@ -41,8 +41,9 @@ type VolumeParams struct {
4141
// NewVolumeParams parses the input params and instantiates new VolumeParams.
4242
func NewVolumeParams(m map[string]string) (*VolumeParams, error) {
4343
params := &VolumeParams{ // set up defaults, if any.
44-
Scheduler: CapacityWeighted,
45-
Shared: "no",
44+
Scheduler: CapacityWeighted,
45+
Shared: "no",
46+
ThinProvision: "no",
4647
}
4748
// parameter keys may be mistyped from the CRD specification when declaring
4849
// the storageclass, which kubectl validation will not catch. Because
@@ -53,8 +54,9 @@ func NewVolumeParams(m map[string]string) (*VolumeParams, error) {
5354

5455
// parse string params
5556
stringParams := map[string]*string{
56-
"scheduler": &params.Scheduler,
57-
"shared": &params.Shared,
57+
"scheduler": &params.Scheduler,
58+
"shared": &params.Shared,
59+
"thinprovision": &params.ThinProvision,
5860
}
5961
for key, param := range stringParams {
6062
value, ok := m[key]

pkg/lvm/lvm_util.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,29 @@ func buildLVMCreateArgs(vol *apis.LVMVolume) []string {
7676

7777
volume := vol.Name
7878
size := vol.Spec.Capacity + "b"
79+
// thinpool name required for thinProvision volumes
80+
pool := vol.Spec.VolGroup + "_thinpool"
7981

8082
if len(vol.Spec.Capacity) != 0 {
81-
LVMVolArg = append(LVMVolArg, "-L", size)
83+
// check if thin pool exists for given volumegroup requested thin volume
84+
if strings.TrimSpace(vol.Spec.ThinProvision) != "yes" || !lvThinExists(vol.Spec.VolGroup, pool) {
85+
LVMVolArg = append(LVMVolArg, "-L", size)
86+
}
87+
}
88+
89+
// command to create thinpool and thin volume if thinProvision is enabled
90+
// `lvcreate -L 1G -T lvmvg/mythinpool -V 1G -n thinvol`
91+
if strings.TrimSpace(vol.Spec.ThinProvision) == "yes" {
92+
LVMVolArg = append(LVMVolArg, "-T", vol.Spec.VolGroup+"/"+pool, "-V", size)
8293
}
8394

8495
if len(vol.Spec.VolGroup) != 0 {
8596
LVMVolArg = append(LVMVolArg, "-n", volume)
8697
}
8798

88-
LVMVolArg = append(LVMVolArg, vol.Spec.VolGroup)
89-
99+
if strings.TrimSpace(vol.Spec.ThinProvision) != "yes" {
100+
LVMVolArg = append(LVMVolArg, vol.Spec.VolGroup)
101+
}
90102
return LVMVolArg
91103
}
92104

@@ -392,3 +404,14 @@ func ListLVMVolumeGroup() ([]apis.VolumeGroup, error) {
392404
}
393405
return decodeVgsJSON(output)
394406
}
407+
408+
// lvThinExists verifies if thin pool/volume already exists for given volumegroup
409+
func lvThinExists(vg string, name string) bool {
410+
cmd := exec.Command("lvs", vg+"/"+name, "--noheadings", "-o", "lv_name")
411+
out, err := cmd.CombinedOutput()
412+
if err != nil {
413+
klog.Infof("unable to list existing volumes:%v", err)
414+
return false
415+
}
416+
return name == strings.TrimSpace(string(out))
417+
}

0 commit comments

Comments
 (0)