Skip to content

Commit

Permalink
chore(lvm): add support to configure auto lvm thin pool expansion cap…
Browse files Browse the repository at this point in the history
…ability to e2e agent

Signed-off-by: rohan2794 <[email protected]>
  • Loading branch information
rohan2794 committed Sep 25, 2024
1 parent fc172d5 commit 3a5d4cd
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 16 deletions.
26 changes: 25 additions & 1 deletion common/e2e_agent/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ type Lvm struct {
Pv string `json:"pv"` // Physical volume
Vg string `json:"vg"` // Volume group
ThinPoolAutoExtendThreshold int `json:"thinPoolAutoExtendThreshold"` // thin pool auto extend threshold
ThinPoolAutoExtendPercent int `json:"ThinPoolAutoExtendPercent"` // thin pool auto extend percent
ThinPoolAutoExtendPercent int `json:"thinPoolAutoExtendPercent"` // thin pool auto extend percent
}

type LoopDevice struct {
Expand Down Expand Up @@ -1095,3 +1095,27 @@ func RemoveHostPathDisk(serverAddr string, diskPath string, mountPoint string) e
logf.Log.Info("RemoveHostPathDisk succeeded", "output", out)
return err
}

// LvmLvChangeMonitor monitor lvm lv
func LvmLvChangeMonitor(serverAddr string, vgName string) (string, error) {
data := Lvm{
Vg: vgName,
}
logf.Log.Info("Executing lvchange", "addr", serverAddr, "data", data)
url := "http://" + getAgentAddress(serverAddr) + "/lvmlvchangemonitor"
encodedresult, err := sendRequestGetResponse("POST", url, data, false)
if err != nil {
logf.Log.Info("sendRequestGetResponse", "encodedresult", encodedresult, "error", err.Error())
return encodedresult, err
}
out, e2eagenterrcode, err := UnwrapResult(encodedresult)
if err != nil {
logf.Log.Info("unwrap failed", "encodedresult", encodedresult, "error", err.Error())
return encodedresult, err
}
if e2eagenterrcode != ErrNone {
return out, fmt.Errorf("failed to monitor lvm lv, errcode %d", e2eagenterrcode)
}
logf.Log.Info("LvmLvChangeMonitor succeeded", "output", out)
return out, err
}
55 changes: 55 additions & 0 deletions common/lvm/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,58 @@ func SetupLvmNodes(vgName string, size int64) (LvmNodesDevicePvVgConfig, error)
err = lvmNodeConfig.ConfigureLvmNodesWithDeviceAndVg()
return lvmNodeConfig, err
}

// EnableLvmThinPoolAutoExpansion enable auto extending of the Thin Pool (Configure Over-Provisioning protection)
func EnableLvmThinPoolAutoExpansion(vgName string, thinPoolAutoExtendThreshold, thinPoolAutoExtendPercent int) error {

workerNodes, err := ListLvmNode(common.NSOpenEBS())
if err != nil {
return fmt.Errorf("failed to list lvm worker nodes, error: %v", err)
}
if len(workerNodes) == 0 {
return fmt.Errorf("lvm worker nodes not found")
}
/*
1. Since we automatically create thin pool as part of first thin volume provisioning,
we need to enable the monitoring using lvchange command on the all thin pools across
the nodes to use the auto extend threshold feature.
monitor lvm lv thin pool
lvchange --monitor y lvmvg/lvmvg_thinpool
2. Editing the settings in the /etc/lvm/lvm.conf can allow auto growth of the thin pool when required.
By default, the threshold is 100% which means that the pool will not grow.
If we set this to, 75%, the Thin Pool will autoextend when the pool is 75% full.
It will increase by the default percentage of 20% if the value is not changed.
We can see these settings using the command grep against the file.
$ grep -E ‘^\s*thin_pool_auto’ /etc/lvm/lvm.conf
thin_pool_autoextend_threshold = 100
thin_pool_autoextend_percent = 20
*/

for _, node := range workerNodes {
nodeIp, err := k8stest.GetNodeIPAddress(node)
if err != nil {
return fmt.Errorf("failed to get node %s IP, error: %v", node, err)
}
out, err := e2e_agent.LvmLvChangeMonitor(*nodeIp, vgName)
if err != nil {
return fmt.Errorf("failed to set up lv monitor for vg %s on node %s,output: %s error: %v",
vgName, node, out, err)
}

out, err = e2e_agent.LvmThinPoolAutoExtendThreshold(*nodeIp, thinPoolAutoExtendThreshold)
if err != nil {
return fmt.Errorf("failed to set up thin_pool_autoextend_threshold value %d on node %s,output: %s error: %v",
thinPoolAutoExtendThreshold, node, out, err)
}

out, err = e2e_agent.LvmThinPoolAutoExtendPercent(*nodeIp, thinPoolAutoExtendPercent)
if err != nil {
return fmt.Errorf("failed to set up thin_pool_autoextend_percent value %d on node %s,output: %s error: %v",
thinPoolAutoExtendPercent, node, out, err)
}

}

return nil
}
2 changes: 1 addition & 1 deletion tools/e2e-agent/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ COPY ./ /
# It ensures that devices are configured as soon as they are plugged in and discovered.
# It propagates information about a processed device.
RUN apt-get update; apt-get install net-tools iptables wget parted udev nvme-cli build-essential gettext gettext-base \
libinih-dev uuid-dev liburcu-dev libblkid-dev btrfs-progs lvm2 zfsutils-linux -y;
libinih-dev uuid-dev liburcu-dev libblkid-dev btrfs-progs -y;
RUN wget https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz; \
tar -C /usr/local/ -xzf go${GO_VERSION}.linux-amd64.tar.gz; \
rm -rf go${GO_VERSION}.linux-amd64.tar.gz; \
Expand Down
2 changes: 1 addition & 1 deletion tools/e2e-agent/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# as long as we do not make breaking changes.
set -e
IMAGE="openebs/e2e-agent"
TAG="v3.0.3"
TAG="v3.0.4"
registry=""
tag_as_latest=""

Expand Down
18 changes: 17 additions & 1 deletion tools/e2e-agent/e2e-agent.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ data:
else
chroot /host zfs "$@"
fi
LVM: |
#!/bin/sh
if [ -x /host/sbin/lvm ]; then
chroot /host /sbin/lvm "$@"
elif [ -x /host/usr/sbin/lvm ]; then
chroot /host /usr/sbin/lvm "$@"
else
chroot /host lvm "$@"
fi
---
kind: DaemonSet
Expand Down Expand Up @@ -50,7 +59,7 @@ spec:
securityContext:
privileged: true
allowPrivilegeEscalation: true
image: openebs/e2e-agent:v3.0.3
image: openebs/e2e-agent:v3.0.4
imagePullPolicy: Always
volumeMounts:
- name: host-root
Expand All @@ -63,6 +72,9 @@ spec:
- mountPath: /sbin/zfs
name: chroot-zfs
subPath: ZFS
- mountPath: /sbin/lvm
name: chroot-lvm
subPath: LVM
volumes:
- name: host-root
hostPath:
Expand All @@ -80,6 +92,10 @@ spec:
configMap:
defaultMode: 0555
name: test-vars
- name: chroot-lvm
configMap:
defaultMode: 0555
name: test-vars


---
55 changes: 43 additions & 12 deletions tools/e2e-agent/lvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type Lvm struct {
Pv string `json:"pv"` // Physical volume
Vg string `json:"vg"` // Volume group
ThinPoolAutoExtendThreshold int `json:"thinPoolAutoExtendThreshold"` // thin pool auto extend threshold
ThinPoolAutoExtendPercent int `json:"ThinPoolAutoExtendPercent"` // thin pool auto extend percent
ThinPoolAutoExtendPercent int `json:"thinPoolAutoExtendPercent"` // thin pool auto extend percent
}

// LvmVersion check lvm version installed on node
Expand All @@ -36,7 +36,7 @@ func LvmListVg(w http.ResponseWriter, r *http.Request) {
var msg string
klog.Info("List lvm vgs")

lvmListCommand := "vgs --reportformat json"
lvmListCommand := "lvm vgs --reportformat json"
output, err := bashLocal(lvmListCommand)
if err != nil {
msg = fmt.Sprintf("cannot list lvm vgs Error %s", err.Error())
Expand All @@ -52,7 +52,7 @@ func LvmListPv(w http.ResponseWriter, r *http.Request) {
var msg string
klog.Info("List lvm pvs")

lvmListCommand := "pvs --reportformat json"
lvmListCommand := "lvm pvs --reportformat json"
output, err := bashLocal(lvmListCommand)
if err != nil {
msg = fmt.Sprintf("cannot list lvm pvs Error %s", err.Error())
Expand Down Expand Up @@ -82,7 +82,7 @@ func LvmCreatePv(w http.ResponseWriter, r *http.Request) {
}
klog.Info("creates lvm pv, data: %v", lvm)

lvmPvCreateCommand := fmt.Sprintf("pvcreate %s", lvm.Pv)
lvmPvCreateCommand := fmt.Sprintf("lvm pvcreate %s", lvm.Pv)
output, err := bashLocal(lvmPvCreateCommand)
if err != nil {
msg = fmt.Sprintf("cannot create lvm pv Error %s", err.Error())
Expand Down Expand Up @@ -118,7 +118,7 @@ func LvmCreateVg(w http.ResponseWriter, r *http.Request) {
}
klog.Info("creates lvm vg, data: %v", lvm)

lvmVgCreateCommand := fmt.Sprintf("vgcreate %s %s", lvm.Vg, lvm.Pv)
lvmVgCreateCommand := fmt.Sprintf("lvm vgcreate %s %s", lvm.Vg, lvm.Pv)
output, err := bashLocal(lvmVgCreateCommand)
if err != nil {
msg = fmt.Sprintf("cannot create lvm vg Error %s", err.Error())
Expand Down Expand Up @@ -148,7 +148,7 @@ func LvmRemovePv(w http.ResponseWriter, r *http.Request) {
}
klog.Info("remove lvm pv, data: %v", lvm)

lvmPvRemoveCommand := fmt.Sprintf("pvremove %s", lvm.Pv)
lvmPvRemoveCommand := fmt.Sprintf("lvm pvremove %s", lvm.Pv)
output, err := bashLocal(lvmPvRemoveCommand)
if err != nil {
msg = fmt.Sprintf("cannot remove lvm pv Error %s", err.Error())
Expand Down Expand Up @@ -178,7 +178,7 @@ func LvmRemoveVg(w http.ResponseWriter, r *http.Request) {
}
klog.Info("remove lvm vg, data: %v", lvm)

lvmVgRemoveCommand := fmt.Sprintf("vgremove %s", lvm.Vg)
lvmVgRemoveCommand := fmt.Sprintf("lvm vgremove %s", lvm.Vg)
output, err := bashLocal(lvmVgRemoveCommand)
if err != nil {
msg = fmt.Sprintf("cannot create lvm vg Error %s", err.Error())
Expand Down Expand Up @@ -208,7 +208,7 @@ func LvmThinPoolAutoExtendThreshold(w http.ResponseWriter, r *http.Request) {
}
klog.Info("update lvm.conf thin pool auto extend threshold value, data: %v", lvm)

lvmThinPoolAutoExtentThresholdCommand := fmt.Sprintf("sed -i '/^[^#]*thin_pool_autoextend_threshold/ s/= .*/= %d/' /etc/lvm/lvm.conf",
lvmThinPoolAutoExtentThresholdCommand := fmt.Sprintf("sed -i '/^[^#]*thin_pool_autoextend_threshold/ s/= .*/= %d/' /host/etc/lvm/lvm.conf",
lvm.ThinPoolAutoExtendThreshold)
output, err := bashLocal(lvmThinPoolAutoExtentThresholdCommand)
if err != nil {
Expand All @@ -231,17 +231,17 @@ func LvmThinPoolAutoExtendPercent(w http.ResponseWriter, r *http.Request) {
WrapResult(msg, ErrJsonDecode, w)
return
}
if lvm.ThinPoolAutoExtendThreshold <= 0 {
msg = "no thin pool auto extent percent passed"
if lvm.ThinPoolAutoExtendPercent <= 0 {
msg = "no thin pool auto extend percent passed"
klog.Error(msg)
WrapResult(msg, UnprocessableEntityErrorCode, w)
return
}
klog.Info("update lvm.conf thin pool auto extend threshold value, data: %v", lvm)

lvmThinPoolAutoExtentPercentCommand := fmt.Sprintf("sed -i '/^[^#]*thin_pool_autoextend_percent/ s/= .*/= %d/' /etc/lvm/lvm.conf",
lvmThinPoolAutoExtendPercentCommand := fmt.Sprintf("sed -i '/^[^#]*thin_pool_autoextend_percent/ s/= .*/= %d/' /host/etc/lvm/lvm.conf",
lvm.ThinPoolAutoExtendPercent)
output, err := bashLocal(lvmThinPoolAutoExtentPercentCommand)
output, err := bashLocal(lvmThinPoolAutoExtendPercentCommand)
if err != nil {
msg = fmt.Sprintf("update lvm.conf thin pool auto extend percent value, Error %s", err.Error())
klog.Error(msg)
Expand All @@ -250,3 +250,34 @@ func LvmThinPoolAutoExtendPercent(w http.ResponseWriter, r *http.Request) {
}
WrapResult(output, ErrNone, w)
}

// LvmLvChangeMonitor monitor lvm lv
func LvmLvChangeMonitor(w http.ResponseWriter, r *http.Request) {
var msg string
var lvm Lvm
d := json.NewDecoder(r.Body)
if err := d.Decode(&lvm); err != nil {
msg = fmt.Sprintf("failed to read JSON encoded data, Error: %s", err.Error())
klog.Error(msg)
WrapResult(msg, ErrJsonDecode, w)
return
}

if lvm.Vg == "" {
msg = "no vg name passed"
klog.Error(msg)
WrapResult(msg, UnprocessableEntityErrorCode, w)
return
}
klog.Info("monitor lvm lv, data: %v", lvm)

lvmLvMonitorCommand := fmt.Sprintf("lvchange --monitor y %s/%s_thinpool", lvm.Vg, lvm.Vg)
output, err := bashLocal(lvmLvMonitorCommand)
if err != nil {
msg = fmt.Sprintf("cannot monitor lvm lv, Error %s", err.Error())
klog.Error(msg)
WrapResult(msg, ErrExecFailed, w)
return
}
WrapResult(output, ErrNone, w)
}
1 change: 1 addition & 0 deletions tools/e2e-agent/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ func handleRequests() {
router.HandleFunc("/lvmremovevg", LvmRemoveVg).Methods("POST")
router.HandleFunc("/lvmthinpoolautoextendthreshold", LvmThinPoolAutoExtendThreshold).Methods("POST")
router.HandleFunc("/lvmthinpoolautoextendpercent", LvmThinPoolAutoExtendPercent).Methods("POST")
router.HandleFunc("/lvmlvchangemonitor", LvmLvChangeMonitor).Methods("POST")
//loop device
router.HandleFunc("/createloopdevice", CreateLoopDevice).Methods("POST")
router.HandleFunc("/deleteloopdevice", DeleteLoopDevice).Methods("POST")
Expand Down

0 comments on commit 3a5d4cd

Please sign in to comment.