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

Implement ansible module for management of libvirt volumes #180

Open
wants to merge 45 commits into
base: main
Choose a base branch
from

Conversation

NK308
Copy link

@NK308 NK308 commented Oct 24, 2024

SUMMARY

This PR adds a module to create, delete and modify libvirt volumes.

This PR is based on the fork which was subject of #45

ISSUE TYPE
  • New Module Pull Request
COMPONENT NAME

virt_volume

ADDITIONAL INFORMATION

Some of the code of the new ansible module as well as parts of the code of virt_pool, have been refactored to module_utils to reduce redundancy.
For now I have only tested the simple creation und deletion of storage volumes, so there might some more testing be needed.
For now I didn't do much more, compared to #45, than bringing the branch up to date with the main branch, including the adoption of changes in the code and doc style from the other modules.

galli-leo and others added 30 commits September 2, 2020 01:43
Trying to define a volume, that already exists caused the integration test
to fail with a traceback that implies, a code block has been executed,
which should have been skipped in the case of the target volume already
existing.
The previous code based on raising and catching an exception in case the
volume does not already exist, but resulting in the exception bein risen
anyway during the test, which lead to the failure.
This commit replaces the exception based check in hope to fix this bug.
…nged Trying to define a volume, that already exists caused the integration test to fail with a traceback that implies, a code block has been executed, which should have been skipped in the case of the target volume already existing. The previous code based on raising and catching an exception in case the volume does not already exist, but resulting in the exception bein risen anyway during the test, which lead to the failure. This commit replaces the exception based check in hope to fix this bug.
@NK308
Copy link
Author

NK308 commented Oct 29, 2024

"no connection driver available for qemu:///system" is a new error, and I'm not able to tell, why it starts showing up exactly now, and not earlier.

@Andersson007
Copy link
Contributor

I'm unfortunately completely unfamiliar with the technology and have no idea about why the tests fail
@csmart @drybjed @odyssey4me any thoughts?

@Andersson007
Copy link
Contributor

@NK308 i took a quick look, i see you test on very old distros, how about just testing only on ubuntu 24.04 if it makes sense?

@NK308
Copy link
Author

NK308 commented Nov 12, 2024

@Andersson007 The issue seems to be very specific to the RHEL remote targets, even the current version, while older versions of other operating systems don't seem to cause any problems.
I was also assuming, a PR has to pass those targets to be accepted to a collection in the community namespace.

@Andersson007
Copy link
Contributor

@Andersson007 The issue seems to be very specific to the RHEL remote targets, even the current version, while older versions of other operating systems don't seem to cause any problems. I was also assuming, a PR has to pass those targets to be accepted to a collection in the community namespace.

@NK308 my comment is not related to the failures, i just think it's an extra thing and there's no such a requirement to test against them. I'm not familiar with the technology though and I don't know if it's distro dependent or not.
If it is, it makes sense to test against several relevant distros but I guess it doesn't make sense to test on not supported ones.

@NK308
Copy link
Author

NK308 commented Nov 12, 2024

I now have removed the OS specific variables from the integration tests, if that's what you meant. The remaining operating systems represented in tests/integration/targets/virt_volume/vars are actually not yet end of life, despite being old, or at least still receive some kind of extended support.

@Andersson007
Copy link
Contributor

@NK308 how about removing RH 7 and updating Ubuntu 16 to 24.04 ?

@NK308
Copy link
Author

NK308 commented Nov 18, 2024

Those versions are not end of life yet, and servers can still receive extended support, as stated here https://en.wikipedia.org/wiki/Ubuntu_version_history and here https://en.wikipedia.org/wiki/Red_Hat_Enterprise_Linux.
That's why I don't consider it a good idea to remove something related to those system.

@csmart
Copy link
Collaborator

csmart commented Nov 23, 2024

Hi @NK308 thanks very much for reviving this, I'll take a look and put in any comments in line.

Copy link
Collaborator

@csmart csmart left a comment

Choose a reason for hiding this comment

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

@NK308 thanks again for this, I've done an initial review with comments in line, if you have time to take a look that would be great. I think one of the things we should consider is perhaps combining the volume and pool tests as volume is dependent on a pool, or reworking them to have some common parts to call. Also, I think it'd be great if the format of the volume tests were similar in style to the pool tests, e.g. with "check" mode, etc. I did test check mode but it didn't seem to behave as expected, so that might need some attention (but that's an inline comment). Feel free to let me know how you go and if you need a hand. Thanks!

rc = VIRT_SUCCESS
try:
rc, result = core(module)
except Exception as e:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe we can add a custom exception for this, like with EntryNotFound(Exception)?

Copy link
Author

@NK308 NK308 Dec 9, 2024

Choose a reason for hiding this comment

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

The module es already using EntryNotFoundand at the end of the main method any exception should be caught. That's why Exception is caught there.

v = VirtVolume(uri, module, pool)
res = {}

if state and command == 'list_volumes':
Copy link
Collaborator

Choose a reason for hiding this comment

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

is state actually used here? state is being passed to list_volumes but AFAICT it's not used by find_entry or listAllStoragePools()...

aliases: [ "volume" ]
description:
- Name of the volume being managed. Note that the volume must be previously
defined with xml.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think maybe we should add a note here that name is required if state is defined?

description:
- Specify which state you want a volume to be in.
If 'present', ensure that the volume is present but do not change its
state; if it's missing, you need to specify xml argument.
Copy link
Collaborator

Choose a reason for hiding this comment

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

suggest, if it's missing, you need to define it by specifying the xml argument.

@@ -0,0 +1,85 @@
---
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder whether it might be better to include virt_volume tests as a part of the virt_pool test, as the pools are a dependency and it would save time and duplication?...

tests/integration/targets/virt_volume/tasks/main.yml Outdated Show resolved Hide resolved
tests/integration/targets/virt_volume/vars/Debian.yml Outdated Show resolved Hide resolved
xml=dict(),
mode=dict(choices=ALL_MODES),
),
supports_check_mode=True
Copy link
Collaborator

Choose a reason for hiding this comment

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

in my testing, it doesn't seem like check mode is working as expected, defining a volume in a pool with check_mode: true still creates the volume

volume doesn't exist:

$ sudo ls -l /var/lib/libvirt/images/testing-volume
ls: cannot access '/var/lib/libvirt/images/testing-volume': No such file or directory

$ sudo virsh vol-info testing-volume default
error: failed to get vol 'testing-volume'
error: Storage volume not found: no storage vol with matching path 'testing-volume'

test with ansible playbook volume_test.yml:

---
- hosts: localhost
  gather_facts: false
  become: true
  tasks:
    - name: "Define volume on check_mode(pre)"
      community.libvirt.virt_volume:
        state: present
        name: testing-volume
        pool: default
        xml: |
            <volume>
              <name>testing-volume</name>
              <allocation>0</allocation>
              <capacity unit="M">10</capacity>
              <target>
                <permissions>
                  <mode>0644</mode>
                  <label>virt_image_t</label>
                </permissions>
              </target>
            </volume>
      check_mode: true

run ansible, changed as expected:

$ ansible-playbook -i localhost, -K volume_test.yml 
BECOME password: 

PLAY [localhost] *****************************************************************************************************

TASK [Define volume on check_mode(pre)] ******************************************************************************
changed: [localhost]

PLAY RECAP ***********************************************************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

check volume, was incorrectly created:

$ sudo ls -l /var/lib/libvirt/images/testing-volume
-rw-r--r--. 1 root root 10485760 Nov 24 15:56 /var/lib/libvirt/images/testing-volume

$ sudo virsh vol-info testing-volume default
Name:           testing-volume
Type:           file
Capacity:       10.00 MiB
Allocation:     0.00 B

@NK308
Copy link
Author

NK308 commented Dec 4, 2024

The original branch from @flagbot on which my branch is based, had shared code between the virt_storage and virt_pool modules, but @Andersson007 recommended me to put anything, that involves the total refactoring of an already existing module, into a separate PR. That's why I basically reversed the refactoring that exists in https://github.com/flagbot/community.libvirt/tree/feature/virt_volume.

@Andersson007
Copy link
Contributor

The original branch from @flagbot on which my branch is based, had shared code between the virt_storage and virt_pool modules, but @Andersson007 recommended me to put anything, that involves the total refactoring of an already existing module, into a separate PR. That's why I basically reversed the refactoring that exists in https://github.com/flagbot/community.libvirt/tree/feature/virt_volume.

@NK308 can we incorporate any of the suggestions by @csmart or you think it's sufficient for merge as is? I can't provide any feedback on the refactoring but it'm for keeping unrelated things separate (i.e. in separate PRs).

@NK308
Copy link
Author

NK308 commented Dec 9, 2024

The original branch from @flagbot on which my branch is based, had shared code between the virt_storage and virt_pool modules, but @Andersson007 recommended me to put anything, that involves the total refactoring of an already existing module, into a separate PR. That's why I basically reversed the refactoring that exists in https://github.com/flagbot/community.libvirt/tree/feature/virt_volume.

@NK308 can we incorporate any of the suggestions by @csmart or you think it's sufficient for merge as is? I can't provide any feedback on the refactoring but it'm for keeping unrelated things separate (i.e. in separate PRs).

I think, the best thing would be, to incorporate some of the smaller changes, merge this PR, then do some refactoring in a second PR and then handling the stuff about the diffs and checks in a third PR.

But thinking about the diffs... I can think about some features, that would have some overlapp with that topic, like a command which would be to able to edit/update things like domains or networks. I mean ... both features would require code to do a more in-depth analysis of the xml definitions, that I can find here right now. This might hold for the freatures of #183 (I didn't really take a look into it jet).

So before we do the refactoring, we might want to have a more in-depth discussion about how we want the outline of the code in module_utils to look like, and how it should look like, to provide a good foundation for new features in the future.
At least to me, the point, where we start to refactor common code into module_utils, seems to be the right point in time for this discussion.

Copy link
Contributor

@Andersson007 Andersson007 left a comment

Choose a reason for hiding this comment

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

Cool, let's proceed, I can help with a general review, there we go

- Manage I(libvirt) volumes inside a storage pool.
options:
name:
aliases: [ "volume" ]
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
aliases: [ "volume" ]

Only name is ok here, there's a recommendation in the docs to avoid aliases whenever possible

Copy link
Author

Choose a reason for hiding this comment

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

I think, the aliases are a good idea here, because in playbooks with lots of tasks from community.libvirt it improves the readability, to not have every task contain a name which references to a totally different kind of structure.

plugins/modules/virt_volume.py Outdated Show resolved Hide resolved

module = AnsibleModule(
argument_spec=dict(
name=dict(aliases=['volume']),
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
name=dict(aliases=['volume']),
name=dict(),

Comment on lines +23 to +24
- Name of the volume being managed. Note that the volume must be previously
defined with xml.
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
- Name of the volume being managed. Note that the volume must be previously
defined with xml.
- Name of the volume being managed. Note that the volume must be previously
defined with xml.

Is it not required? Just to be sure

Copy link
Author

Choose a reason for hiding this comment

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

It is required, with the exception of the list_volumes, info and facts command.

- Leonardo Galli (@galli-leo)
short_description: Manage libvirt volumes inside a storage pool
description:
- Manage I(libvirt) volumes inside a storage pool.
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
- Manage I(libvirt) volumes inside a storage pool.
- Manage I(libvirt) volumes inside a storage pool.
attributes:
check_mode:
description: Supports check_mode.
support: full

plugins/modules/virt_volume.py Show resolved Hide resolved
@Andersson007
Copy link
Contributor

I would highly suggest updating ubuntu 16 to at least 22 or better 24 and RedHat to the latest. Those old ones are really old and receive only security updates

@csmart
Copy link
Collaborator

csmart commented Dec 17, 2024

The original branch from @flagbot on which my branch is based, had shared code between the virt_storage and virt_pool modules, but @Andersson007 recommended me to put anything, that involves the total refactoring of an already existing module, into a separate PR. That's why I basically reversed the refactoring that exists in https://github.com/flagbot/community.libvirt/tree/feature/virt_volume.

Different MR for unrelated features is good, but I'm also wary of merging something for which the coverage of the tests isn't quite complete and then it never gets fixed up later. Duplication is fine, but I think the check is something that probably should be fixed here to help create a complete test. But if @Andersson007 prefers to merge it as it is, then we can work on that and try to clean it up later.

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.

5 participants