ansible-collections / community.general

Ansible Community General Collection
https://galaxy.ansible.com/ui/repo/published/community/general/
GNU General Public License v3.0
838 stars 1.53k forks source link

GPT disk is not fixed before resizing it #1461

Open smutel opened 3 years ago

smutel commented 3 years ago
SUMMARY

An error message is displayed when we would like to increase the size of disk using collection parted.

ISSUE TYPE
COMPONENT NAME

parted

ANSIBLE VERSION
2.10.3
CONFIGURATION
ANSIBLE_PIPELINING = True
ANSIBLE_SSH_ARGS = -o ControlMaster=auto -o ControlPersist=30m -o ConnectionAttempts=100 -o UserKnownHostsFile=/dev/null
CACHE_PLUGIN = jsonfile
CACHE_PLUGIN_CONNECTION = /tmp/ansible_facts
CACHE_PLUGIN_TIMEOUT = 86400
DEFAULT_BECOME = True
DEFAULT_FORKS = 30
DEFAULT_GATHERING = smart
DEFAULT_GATHER_TIMEOUT = 90
DEFAULT_STDOUT_CALLBACK = yaml
DEFAULT_VAULT_IDENTITY_LIST = ['roles/dw-pure-client/vault/decrypt.sh']
HOST_KEY_CHECKING = False
INVENTORY_ENABLED = ['advanced_host_list', 'script', 'constructed', 'yaml', 'ini']
RETRY_FILES_ENABLED = False
OS / ENVIRONMENT
STEPS TO REPRODUCE
- name: Create a new primary partition for LVM
      parted:
        device: "/dev/mapper/mpath{{ '%c' | format(item + 97) }}"
        label: gpt
        number: 1
        flags: [lvm]
        state: present
        unit: '%'
        resize: yes
      loop: "{{ range(0, pure_volumes | length) | list }}"
EXPECTED RESULTS

Disk is resized correctly.

ACTUAL RESULTS
failed: [xxxxxx] (item=0) => changed=false 
  ansible_facts:
    discovered_interpreter_python: /usr/bin/python
  ansible_loop_var: item
  err: |-
    Warning: Not all of the space available to /dev/mapper/mpatha appears to be used, you can fix the GPT to use all of the space (an extra 16777216 blocks) or continue with the current setting?
    Error: Unable to satisfy all constraints on the partition.
  item: 0
  msg: 'Error while running parted script: /usr/sbin/parted -s -m -a optimal /dev/mapper/mpatha -- resizepart 1 100%'
  out: ''
  rc: 1
ansibullbot commented 3 years ago

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

ansibullbot commented 3 years ago

cc @ColOfAbRiX @jake2184 @rosowiecki click here for bot help

jake2184 commented 3 years ago

Could you give a bit more detail about the disk setup (as in if you've just expand a virtual disk etc), and the OS + parted version? I'll try and replicate on Centos8.

Note that the module shells out to parted, which possibly might not support fixing the GPT table in script mode (see here). That would require a bit more reworking of the module.

rosowiecki commented 3 years ago

[edited] The parted command used by ansible module (resizepart 1 100%) seems valid.

@smutel: could you please run the comman /usr/sbin/parted -s -m -a optimal /dev/mapper/mpatha -- resizepart 1 100% outside of ansible and see what happens? Also: try without -s option and see what happens.

I've noticed you used /dev/mapper path to your device. Did you use LVM or similar to increase its size before using parted module? Parted seems to be confused that underlying device size has changed; resize command was meant to increase size of partition, not whole device and that could cause your problem too.

rosowiecki commented 3 years ago

I reproduced this situtaion on my PC. If you increase underlying device size, parted asks for permission to adjust GPT table for new size and with -s option it chooses safe exit (cancel). I'm afraid there's little we can do here due to parted (tool, not module) limitations.

Maybe you could skip creating partitions anyway and use /dev/mapper/device_name directly? You want to use 100% of it anyway...

smutel commented 3 years ago

What about executing something like this:

printf "fix\n" | parted ---pretend-input-tty /dev/vda print
rosowiecki commented 3 years ago

I wouldn't trust that at all; what if parted asks about something else (like differrent error in table, not size mismatch) and we'll "fix" it by blowing whole table up :-/ so we should at least agree only for certain well defined problems, and not blindly fix everything parted may come up with. I can imagine parameter like input or expect (see: man expect) script to pipe to or interact with parted and hope the user knows the best... but then: why not use shell module instead? Parted module works by preparing and executing non-interactive parted scripts: extending it to overcome parted's limitations is not a trivial fix, I'm afraid.

jake2184 commented 3 years ago

I've poked around with the module and got it work as requested using pretend-input-tty, but as @rosowiecki states there are a number of drawbacks to this, the most prominent one being that it is hard to identify when we should apply the auto 'fix'. It would rely on matching strings from stdout which might change, be different between OSes/parted versions, etc. I don't think it's within the scope of the module to work around parted's limitation in this way.

I understand the request, as I use the module in a similar way (growing partitions on a disk after it was expanded), and would hit the same problem if the disks had GTP tables. However I think the cleanest workaround is to either fork/extend the module yourself (where you have contextual knowledge so can apply the fix command more safely in the module) or to use shell as suggested above.

smutel commented 3 years ago

And if before executing the fix, we test the need to fix the GPT with something like:


command = "echo \"check\" | parted /dev/vdd print"
rc, out, err = module.run_command(command)
if "Warning: Not all of the space available" in out:
  ...
dmc5179 commented 3 years ago

Could use this to fix just the gpt issue and not blindly fix all errors:

sgdisk /dev/vdd -e
mnlipp commented 2 years ago

parted has an option "-f" which causes he gpt issue to be fixed without asking.

ansibullbot commented 2 years ago

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help