diff --git a/changelog/unreleased/1-pawanpraka1 b/changelogs/unreleased/1-pawanpraka1 similarity index 100% rename from changelog/unreleased/1-pawanpraka1 rename to changelogs/unreleased/1-pawanpraka1 diff --git a/changelog/unreleased/12-akhilerm b/changelogs/unreleased/12-akhilerm similarity index 100% rename from changelog/unreleased/12-akhilerm rename to changelogs/unreleased/12-akhilerm diff --git a/changelog/unreleased/2-pawanpraka1 b/changelogs/unreleased/2-pawanpraka1 similarity index 100% rename from changelog/unreleased/2-pawanpraka1 rename to changelogs/unreleased/2-pawanpraka1 diff --git a/changelogs/unreleased/20-akhilerm b/changelogs/unreleased/20-akhilerm new file mode 100644 index 00000000..6e307bbb --- /dev/null +++ b/changelogs/unreleased/20-akhilerm @@ -0,0 +1 @@ +add capacity weighted scheduler and make it default for scheduling volumes \ No newline at end of file diff --git a/pkg/driver/schd_helper.go b/pkg/driver/schd_helper.go index 72c8914c..06a92613 100644 --- a/pkg/driver/schd_helper.go +++ b/pkg/driver/schd_helper.go @@ -17,21 +17,25 @@ limitations under the License. package driver import ( - "github.com/openebs/lvm-localpv/pkg/builder/volbuilder" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "strconv" + "github.com/openebs/lvm-localpv/pkg/builder/volbuilder" "github.com/openebs/lvm-localpv/pkg/lvm" ) // scheduling algorithm constants const ( // pick the node where less volumes are provisioned for the given volume group - // this will be the default scheduler when none provided VolumeWeighted = "VolumeWeighted" + + // pick the node where total provisioned volumes have occupied less capacity from the given volume group + // this will be the default scheduler when none provided + CapacityWeighted = "CapacityWeighted" ) // getVolumeWeightedMap goes through all the volumegroup on all the nodes -// and creats the node mapping of the volume for all the nodes. +// and creates the node mapping of the volume for all the nodes. // It returns a map which has nodes as key and volumes present // on the nodes as corresponding value. func getVolumeWeightedMap(vg string) (map[string]int64, error) { @@ -56,12 +60,44 @@ func getVolumeWeightedMap(vg string) (map[string]int64, error) { return nmap, nil } +// getCapacityWeightedMap goes through all the volume groups on all the nodes +// and creates the node mapping of the capacity for all the nodes. +// It returns a map which has nodes as key and capacity provisioned +// on the nodes as corresponding value. The scheduler will use this map +// and picks the node which is less weighted. +func getCapacityWeightedMap(vg string) (map[string]int64, error) { + nmap := map[string]int64{} + + volList, err := volbuilder.NewKubeclient(). + WithNamespace(lvm.LvmNamespace). + List(metav1.ListOptions{}) + + if err != nil { + return nmap, err + } + + // create the map of the volume capacity + // for the given volume group + for _, vol := range volList.Items { + if vol.Spec.VolGroup == vg { + volSize, err := strconv.ParseInt(vol.Spec.Capacity, 10, 64) + if err == nil { + nmap[vol.Spec.OwnerNodeID] += volSize + } + } + } + + return nmap, nil +} + // getNodeMap returns the node mapping for the given scheduling algorithm func getNodeMap(schd string, vg string) (map[string]int64, error) { switch schd { case VolumeWeighted: return getVolumeWeightedMap(vg) + case CapacityWeighted: + return getCapacityWeightedMap(vg) } - // return VolumeWeighted(default) if not specified - return getVolumeWeightedMap(vg) + // return CapacityWeighted(default) if not specified + return getCapacityWeightedMap(vg) }