Function to get the current space of a logical volume?

1.3k Views Asked by At

I'm struggling with 1 ansible role. I'm trying to make a role with 2 vars, extra space to add to the volume, and the mount point for example "/disco1" and "1.5g"

Using lvextend to extend my logical volume works, but when you need to add more space you need to get the correct logical volume total size and add the extra space to add. Tasks of the role:

---
- name: Set device name fact
  set_fact:
   device_path : "{{ item.device}}"
  with_items: "{{ansible_mounts}}"
  when: "fs_name in item.mount"
    
- name: Set device name fact
  set_fact:
   device_name : "{{ item.device.split('/')[-1]}}"
  with_items: "{{ansible_mounts}}"
  when: "fs_name in item.mount"
    
     
- name: Set Volume group fact
  set_fact:
   vg_name : "{{ device_name.split('-')[0]}}"
    
    
- name: Set Logical volume fact
  set_fact:
   lv_name : "{{ device_name.split('-')[1]}}"
    
- name: Get current lv space
  shell:  lvs --noheadings -o lv_size '{{ vg_name }}/{{lv_name}}'| sed 's/g//'
  register: lv_size
  no_log: true
- name: debug lv size
  debug:
    msg: "{{lv_size.stdout_lines}}"
    
- name: extend fs
  lvol:
    vg: "{{vg_name}}"
    lv: "{{lv_name}}"
    size: "{{lv_size.stdout_lines  | int  + fs_size_add |int  }}"
    resizefs: yes

Default file: main.yml

---
fs_name: /disco1
fs_size_add: '1.4G'

The problem is that I'm not being able to get the current disk size correctly as an integer to add the desired size to add and the current size.

After all the struggles and with the immense help of the user toydarian there is my role:

tasks/main.yml

    ---
    - name: Set device name fact
      set_fact:
       device_path : "{{ item.device}}"
      with_items: "{{ansible_mounts}}"
      when: "fs_name in item.mount"
    
    
    - set_fact:
       device_name : "{{ item.device.split('/')[-1]}}"
      with_items: "{{ansible_mounts}}"
      when: "fs_name in item.mount"
    
    - name: Set Volume group fact
      set_fact:
       vg_name : "{{ device_name.split('-')[0]}}"
    
    
    - name: Set Logical volume fact
      set_fact:
       lv_name : "{{ device_name.split('-')[1]}}"
    - shell: |
        lvs --noheadings -o lv_size '{{ vg_name }}/{{lv_name}}' |  grep -oPi '\d+.\d+(?=G)'
      register: vsize
    
      #- fail:
      #   msg: "Current volume sie could not be parsed. Not in correct GB format?"
      #when: vsize_stdout | length == 0
    
    - set_fact:
        nsize: "{{ (vsize.stdout | float) + (fs_size_add  | float) }}"
    - debug:
        msg: |
          current size: "{{vsize.stdout}}"
          new size: "{{nsize}}"
    
    
    
    - name: extend fs
      lvol:
        vg: "{{vg_name}}"
        lv: "{{lv_name}}"
        size: "{{ nsize}}G"
        resizefs: yes

defaults/main.yml

    ---
    fs_name: /disco1
    fs_size_add: '0.4'
1

There are 1 best solutions below

8
On BEST ANSWER

Your problems are in this line: size: "{{lv_size.stdout_lines | int + fs_size_add | int }}"

  • lv_size.stdout_lines is a list. When you try to convert it to an int, it will turn out to be 0. Check the documentation.
  • '1.4G' is a string that can not be converted to an int, as it contains a character (G). So that one is 0 as well.
  • The size option actually takes a string, not an int. If it gets an int, it will convert it to a string and treat that as megabytes.

According to the documentation, it should be possible to use percentages to increase the size of a logical volume like this size: "+100%FREE" to extend the volume to use all free space.
You need to use ansible version 2.1 or newer for that to work.
See the lvcreate(8) man-page and the examples in the documentation for more details.

If you can't use percentages, this is how you can calculate the new size of the logical volume:

- shell: |
    lvs --noheadings -o lv_size '{{ vg_name }}/{{lv_name}}' | grep -oP '\d+,\d+(?=g)' | sed "s/,/./"
  register: vsize

- fail:
    msg: "Current volume size could not be parsed. Not in GB?"
  when: vsize.stdout | length == 0

- set_fact:
    nsize: "{{ (vsize.stdout | float) + (fs_size_add | float) }}"

- debug:
    msg: |
      current size: {{ vsize.stdout }}
      new size: {{ nsize }}
  • It will fail if it is not able to parse the current size. E.g. if it is in MB instead of GB.
  • fs_size_add needs to be a parsable float. E.g. 1.4, but NOT 1.4G.