-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update Volume Group utility #73
Conversation
sp98
commented
Jan 16, 2022
- Refactor volume group utility.
- Add helper methods to list Physical Volumes
- Add helper methods to delete VGs and PVs
- Add unit tests for volume group utility
cd58556
to
40a1107
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can just pass devices to vgcreate/vgextend as long as they are not already pvs. The code to filter devices can return the list of unused, matching disks for the VG.
lvmPath = "/usr/sbin/lvm" | ||
extendVGCmd = "/usr/sbin/vgextend" | ||
createVGCmd = "/usr/sbin/vgcreate" | ||
vgRemoveCmd = "/usr/sbin/vgremove" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use a common format. Either
extendVGCmd, createVGCmd, removeVGCmd, removePVCmd
or
vgExtendCmd, vgCreateCmd,vgRemoveCmd, pvRemoveCmd
I prefer the second over the first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated.
pkg/vgmanager/lvm.go
Outdated
// Remove physical volumes | ||
_, err = exec.ExecuteCommandWithOutputAsHost(pvRemoveCmd, vg.PVs...) | ||
if err != nil { | ||
return fmt.Errorf("failed to remove volume group %q. %v", vg.Name, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return fmt.Errorf("failed to remove volume group %q. %v", vg.Name, err) | |
return fmt.Errorf("failed to remove physical volumes for volume group %q. %v", vg.Name, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
|
||
vgFound := false | ||
volumeGroup := &VolumeGroup{} | ||
for _, report := range res.Report { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vgs can take the name of the vg as an argument.
sh-4.4# vgs
VG #PV #LV #SN Attr VSize VFree
vg1 3 0 0 wz--n- <4.37t <4.37t
sh-4.4# vgs vg2
Volume group "vg2" not found
Cannot process volume group vg2
sh-4.4# vgs vg1
VG #PV #LV #SN Attr VSize VFree
vg1 3 0 0 wz--n- <4.37t <4.37t
sh-4.4# vgs vg1 --reportformat json
{
"report": [
{
"vg": [
{"vg_name":"vg1", "pv_count":"3", "lv_count":"0", "snap_count":"0", "vg_attr":"wz--n-", "vg_size":"<4.37t", "vg_free":"<4.37t"}
]
}
]
}
sh-4.4# vgs vg2 --reportformat json
{
"report": [
Volume group "vg2" not found
Cannot process volume group vg2
{
"vg": [
]
}
]
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I try vgs vg2 --reportformat json
, then I need to parse the output again and check for Volume group "vg2" not found
string is present or not. To avoid this parsing, I'm trying get all the vgs first, then a trying to find if vg2
is one of them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't the output just be an empty array?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like vgs returns exit code 5 when trying to list a non-existent VG, which just means command failed. Trying to figure out why would be more difficult than iterating over the list so the current code is fine for now.
Please add a comment that vgs can take take a vg name and that we will look into whether that can be used later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added comment
pkg/vgmanager/lvm.go
Outdated
// Extend extends the volume group only if new physical volumes are available | ||
func (vg VolumeGroup) Extend(exec internal.Executor, pvs []string) error { | ||
// Extend VG only if there is any new Physical Volume | ||
newPVs := listDiff(pvs, vg.PVs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is the pvs list determined? The PVs may still be in use but belong to another volume.
The code currently doesn't create pvs - it is directly creating Vgs from the disks.
From man vgcreate
vgcreate creates a new VG on block devices. If the devices were not previously intialized as PVs with pvcreate(8), vgcreate will initi‐
tialize them, making them PVs. The pvcreate options for initializing devices are also available with vgcreate.
When vgcreate uses an existing PV, that PV's existing values for metadata size, PE start, etc, are used, even if different values are
specified in the vgcreate command. To change these values, first use pvremove on the device.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
filterMatchingDevices
would ensure that pvs
list does not contains PVs that does not belong to other VGs. listDiff
will ensure that we only run vgextend
with new set of PVs
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FilterDevices does not list PVs. It is returning a list of devices only. However, this function is comparing PVs to the PVs in the VG. Based on the current code, the presence of a PV would mean that it is already being used in a VG (as it does not create them explicitly but as part of a vgcreate/vgextend call) so comparing it to a particular VGs PV list is incorrect and unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vgextend command should always contain new physical volumes, else it will fail. This is a bug in the current code as well. For example:
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 19.5G 0 disk
`-sda1 8:1 0 19.5G 0 part /mnt/sda1
sdb 8:16 0 10G 0 disk
sdc 8:32 0 8G 0 disk
sr0 11:0 1 225.6M 0 rom
# vgs
# vgcreate vg1 /dev/sdb
Physical volume "/dev/sdb" successfully created.
Volume group "vg1" successfully created
# vgs
VG #PV #LV #SN Attr VSize VFree
vg1 1 0 0 wz--n- <10.00g <10.00g
# vgextend vg1 /dev/sdb /dev/sdc
Physical volume '/dev/sdb' is already in volume group 'vg1'
Unable to add physical volume '/dev/sdb' to volume group 'vg1'
/dev/sdb: physical volume not initialized.
# vgs
VG #PV #LV #SN Attr VSize VFree
vg1 1 0 0 wz--n- <10.00g <10.00g
#
listdiff
tries to ensure that vgextend
will always use new Physical volumes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed istdiff
b0826fe
to
02021c9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- implementation of invoking vg deletion is in progress?
pkg/vgmanager/lvm.go
Outdated
// Delete deletes a volume group and the physical volumes associated with it | ||
func (vg VolumeGroup) Delete(exec internal.Executor) error { | ||
// Remove Volume Group | ||
vgArgs := []string{vg.Name} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- use
--nolocking
as well? rationale is if the volume group is huge acquiring lock takes time
} | ||
|
||
// GetVolumeGroup returns a volume group along with the associated physical volumes | ||
func GetVolumeGroup(exec internal.Executor, name string) (*VolumeGroup, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Is this function a standby for now as I don't see it's usage?
- I can see some functions as this only with tests but this function seems to be a duplicate or specific case of
ListVolumeGroups
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetVolumeGroup
not used anywhere now.
Since we might move to one CR for each VG now, we can replace ListVolumeGroup
with GetVolumeGroup
. GetVolumeGroup
checks internally if volume group is available or not.
- Add option to list all PVs - Add helper to get, delete, extend VG - Add helper to delete PV Signed-off-by: Santosh Pillai <sapillai@redhat.com>
No. This PR only provides helper function to delete VG and PVs. Its invocation is not included in this PR. |
pkg/vgmanager/lvm_test.go
Outdated
pvCount int | ||
wantErr bool | ||
}{ | ||
{"Invalid volume group name", "invald-vg", 0, true}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit. invalid-vg
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, although i would like to have the output of the vg commands when they are executed successfully.
volumeGroupMap := map[string][]map[string][]VolumeGroup{} | ||
arg := []string{ | ||
// Create creates a new volume group | ||
func (vg VolumeGroup) Create(exec internal.Executor, pvs []string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create, extend and delete methods only returns error...and in case of success we are losing the output , which can be useful in logs just to trace what is happening. Maybe it could be a good idea to return the error and also and output string to provide the output produced by the vg command when it is executed succesfully.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it will be very useful. We would only be interested to know whether vg got created or not. If not, then what's the error.
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: jmolmo, leelavg, nbalacha, sp98 The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Signed-off-by: Santosh Pillai <sapillai@redhat.com>
Signed-off-by: Santosh Pillai <sapillai@redhat.com>
New changes are detected. LGTM label has been removed. |