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 15f8045
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 17 deletions.
50 changes: 49 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,51 @@ 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
}

// LvmLvRemoveThinPool delete lvm thin pool lv
func LvmLvRemoveThinPool(serverAddr string, vgName string) (string, error) {
data := Lvm{
Vg: vgName,
}
logf.Log.Info("Executing lvchange", "addr", serverAddr, "data", data)
url := "http://" + getAgentAddress(serverAddr) + "/lvmlvremovethinpool"
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 remove lvm thin pool lv, errcode %d", e2eagenterrcode)
}
logf.Log.Info("LvmLvRemoveThinPool succeeded", "output", out)
return out, err
}
44 changes: 44 additions & 0 deletions common/lvm/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,47 @@ 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(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")
}
/*
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.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
19 changes: 17 additions & 2 deletions 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,9 @@ spec:
configMap:
defaultMode: 0555
name: test-vars
- name: chroot-lvm
configMap:
defaultMode: 0555
name: test-vars


---
86 changes: 74 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,65 @@ 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("lvm 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)
}

// LvmLvRemoveThinPool lv thin pool
func LvmLvRemoveThinPool(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("remove lvm thin pool lv, data: %v", lvm)

lvmLvMonitorCommand := fmt.Sprintf("lvm lvremove -f --noudevsync %s/%s_thinpool", lvm.Vg, lvm.Vg)
output, err := bashLocal(lvmLvMonitorCommand)
if err != nil {
msg = fmt.Sprintf("cannot remove lvm thin pool lv, Error %s", err.Error())
klog.Error(msg)
WrapResult(msg, ErrExecFailed, w)
return
}
WrapResult(output, ErrNone, w)
}
2 changes: 2 additions & 0 deletions tools/e2e-agent/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ 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")
router.HandleFunc("/lvmlvremovethinpool", LvmLvRemoveThinPool).Methods("POST")
//loop device
router.HandleFunc("/createloopdevice", CreateLoopDevice).Methods("POST")
router.HandleFunc("/deleteloopdevice", DeleteLoopDevice).Methods("POST")
Expand Down

0 comments on commit 15f8045

Please sign in to comment.