Skip to content
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

Merged
merged 3 commits into from
Jan 17, 2022
Merged

Update Volume Group utility #73

merged 3 commits into from
Jan 17, 2022

Conversation

sp98
Copy link
Contributor

@sp98 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

@sp98 sp98 requested a review from nbalacha January 16, 2022 14:21
@sp98 sp98 force-pushed the vg-delete branch 2 times, most recently from cd58556 to 40a1107 Compare January 17, 2022 03:22
Copy link
Contributor

@nbalacha nbalacha left a 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"
Copy link
Contributor

@nbalacha nbalacha Jan 17, 2022

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated.

// 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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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)

Copy link
Contributor Author

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 {
Copy link
Contributor

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": [
              ]
          }
      ]
  }

Copy link
Contributor Author

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.

Copy link
Contributor

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?

Copy link
Contributor

@nbalacha nbalacha Jan 17, 2022

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added comment

// 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)
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed istdiff

@sp98 sp98 force-pushed the vg-delete branch 3 times, most recently from b0826fe to 02021c9 Compare January 17, 2022 07:17
@sp98 sp98 requested a review from nbalacha January 17, 2022 07:20
Copy link
Contributor

@leelavg leelavg left a 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?

// 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}
Copy link
Contributor

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) {
Copy link
Contributor

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?

Copy link
Contributor Author

@sp98 sp98 Jan 17, 2022

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>
@sp98
Copy link
Contributor Author

sp98 commented Jan 17, 2022

  • implementation of invoking vg deletion is in progress?

No. This PR only provides helper function to delete VG and PVs. Its invocation is not included in this PR.

@sp98 sp98 requested a review from leelavg January 17, 2022 07:57
pvCount int
wantErr bool
}{
{"Invalid volume group name", "invald-vg", 0, true},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit. invalid-vg

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Jan 17, 2022
Copy link
Contributor

@leelavg leelavg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

Copy link
Contributor

@jmolmo jmolmo left a 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 {
Copy link
Contributor

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.

Copy link
Contributor Author

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.

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 17, 2022

[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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

sp98 added 2 commits January 17, 2022 17:25
Signed-off-by: Santosh Pillai <sapillai@redhat.com>
Signed-off-by: Santosh Pillai <sapillai@redhat.com>
@openshift-ci openshift-ci bot removed the lgtm Indicates that a PR is ready to be merged. label Jan 17, 2022
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 17, 2022

New changes are detected. LGTM label has been removed.

@nbalacha nbalacha merged commit 67ffe2f into openshift:main Jan 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants