mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-22 04:40:22 -07:00
[PR #6757/2d6e369d backport][stable-7] [proxmox_template] Fix error while uploading big ISO to Proxmox VE cluster (#6831)
[proxmox_template] Fix error while uploading big ISO to Proxmox VE cluster (#6757)
* [proxmox_template] Fix error while uploading big ISO to Proxmox VE cluster
* Fix pep8 test
* Add changelog fragment
* Add notes about requests_toolbelt
* Check versions and file size
* Fix typo in notes
* Add unit test. Move try inside of each function.
* Fix sanity tests
* Add proxmoxer in requirements file
* Update integration tests
* Add proxmoxer into constraints.txt
* Address review comments
* Don't run tests on 2.6 python
* Disable Python 2.6 tests for other proxmox modules
(cherry picked from commit 2d6e369d81
)
Co-authored-by: Sergei Antipov <greendayonfire@gmail.com>
This commit is contained in:
parent
72d1af86f3
commit
9036d8edd0
10 changed files with 299 additions and 34 deletions
|
@ -65,7 +65,8 @@ options:
|
|||
choices: ['present', 'absent']
|
||||
default: present
|
||||
notes:
|
||||
- Requires C(proxmoxer) and C(requests) modules on host. This modules can be installed with M(ansible.builtin.pip).
|
||||
- Requires C(proxmoxer) and C(requests) modules on host. Those modules can be installed with M(ansible.builtin.pip).
|
||||
- C(proxmoxer) >= 1.2.0 requires C(requests_toolbelt) to upload files larger than 256 MB.
|
||||
author: Sergei Antipov (@UnderGreen)
|
||||
extends_documentation_fragment:
|
||||
- community.general.proxmox.documentation
|
||||
|
@ -123,15 +124,29 @@ EXAMPLES = '''
|
|||
|
||||
import os
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible_collections.community.general.plugins.module_utils.proxmox import (proxmox_auth_argument_spec, ProxmoxAnsible)
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
REQUESTS_TOOLBELT_ERR = None
|
||||
try:
|
||||
# requests_toolbelt is used internally by proxmoxer module
|
||||
import requests_toolbelt # noqa: F401, pylint: disable=unused-import
|
||||
HAS_REQUESTS_TOOLBELT = True
|
||||
except ImportError:
|
||||
HAS_REQUESTS_TOOLBELT = False
|
||||
REQUESTS_TOOLBELT_ERR = traceback.format_exc()
|
||||
|
||||
|
||||
class ProxmoxTemplateAnsible(ProxmoxAnsible):
|
||||
def get_template(self, node, storage, content_type, template):
|
||||
return [True for tmpl in self.proxmox_api.nodes(node).storage(storage).content.get()
|
||||
if tmpl['volid'] == '%s:%s/%s' % (storage, content_type, template)]
|
||||
try:
|
||||
return [True for tmpl in self.proxmox_api.nodes(node).storage(storage).content.get()
|
||||
if tmpl['volid'] == '%s:%s/%s' % (storage, content_type, template)]
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Failed to retrieve template '%s:%s/%s': %s" % (storage, content_type, template, e))
|
||||
|
||||
def task_status(self, node, taskid, timeout):
|
||||
"""
|
||||
|
@ -149,12 +164,24 @@ class ProxmoxTemplateAnsible(ProxmoxAnsible):
|
|||
return False
|
||||
|
||||
def upload_template(self, node, storage, content_type, realpath, timeout):
|
||||
taskid = self.proxmox_api.nodes(node).storage(storage).upload.post(content=content_type, filename=open(realpath, 'rb'))
|
||||
return self.task_status(node, taskid, timeout)
|
||||
stats = os.stat(realpath)
|
||||
if (LooseVersion(self.proxmoxer_version) >= LooseVersion('1.2.0') and
|
||||
stats.st_size > 268435456 and not HAS_REQUESTS_TOOLBELT):
|
||||
self.module.fail_json(msg="'requests_toolbelt' module is required to upload files larger than 256MB",
|
||||
exception=missing_required_lib('requests_toolbelt'))
|
||||
|
||||
try:
|
||||
taskid = self.proxmox_api.nodes(node).storage(storage).upload.post(content=content_type, filename=open(realpath, 'rb'))
|
||||
return self.task_status(node, taskid, timeout)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Uploading template %s failed with error: %s" % (realpath, e))
|
||||
|
||||
def download_template(self, node, storage, template, timeout):
|
||||
taskid = self.proxmox_api.nodes(node).aplinfo.post(storage=storage, template=template)
|
||||
return self.task_status(node, taskid, timeout)
|
||||
try:
|
||||
taskid = self.proxmox_api.nodes(node).aplinfo.post(storage=storage, template=template)
|
||||
return self.task_status(node, taskid, timeout)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Downloading template %s failed with error: %s" % (template, e))
|
||||
|
||||
def delete_template(self, node, storage, content_type, template, timeout):
|
||||
volid = '%s:%s/%s' % (storage, content_type, template)
|
||||
|
@ -199,35 +226,32 @@ def main():
|
|||
timeout = module.params['timeout']
|
||||
|
||||
if state == 'present':
|
||||
try:
|
||||
content_type = module.params['content_type']
|
||||
src = module.params['src']
|
||||
content_type = module.params['content_type']
|
||||
src = module.params['src']
|
||||
|
||||
# download appliance template
|
||||
if content_type == 'vztmpl' and not src:
|
||||
template = module.params['template']
|
||||
# download appliance template
|
||||
if content_type == 'vztmpl' and not src:
|
||||
template = module.params['template']
|
||||
|
||||
if not template:
|
||||
module.fail_json(msg='template param for downloading appliance template is mandatory')
|
||||
if not template:
|
||||
module.fail_json(msg='template param for downloading appliance template is mandatory')
|
||||
|
||||
if proxmox.get_template(node, storage, content_type, template) and not module.params['force']:
|
||||
module.exit_json(changed=False, msg='template with volid=%s:%s/%s already exists' % (storage, content_type, template))
|
||||
|
||||
if proxmox.download_template(node, storage, template, timeout):
|
||||
module.exit_json(changed=True, msg='template with volid=%s:%s/%s downloaded' % (storage, content_type, template))
|
||||
|
||||
template = os.path.basename(src)
|
||||
if proxmox.get_template(node, storage, content_type, template) and not module.params['force']:
|
||||
module.exit_json(changed=False, msg='template with volid=%s:%s/%s is already exists' % (storage, content_type, template))
|
||||
elif not src:
|
||||
module.fail_json(msg='src param to uploading template file is mandatory')
|
||||
elif not (os.path.exists(src) and os.path.isfile(src)):
|
||||
module.fail_json(msg='template file on path %s not exists' % src)
|
||||
module.exit_json(changed=False, msg='template with volid=%s:%s/%s already exists' % (storage, content_type, template))
|
||||
|
||||
if proxmox.upload_template(node, storage, content_type, src, timeout):
|
||||
module.exit_json(changed=True, msg='template with volid=%s:%s/%s uploaded' % (storage, content_type, template))
|
||||
except Exception as e:
|
||||
module.fail_json(msg="uploading/downloading of template %s failed with exception: %s" % (template, e))
|
||||
if proxmox.download_template(node, storage, template, timeout):
|
||||
module.exit_json(changed=True, msg='template with volid=%s:%s/%s downloaded' % (storage, content_type, template))
|
||||
|
||||
template = os.path.basename(src)
|
||||
if proxmox.get_template(node, storage, content_type, template) and not module.params['force']:
|
||||
module.exit_json(changed=False, msg='template with volid=%s:%s/%s is already exists' % (storage, content_type, template))
|
||||
elif not src:
|
||||
module.fail_json(msg='src param to uploading template file is mandatory')
|
||||
elif not (os.path.exists(src) and os.path.isfile(src)):
|
||||
module.fail_json(msg='template file on path %s not exists' % src)
|
||||
|
||||
if proxmox.upload_template(node, storage, content_type, src, timeout):
|
||||
module.exit_json(changed=True, msg='template with volid=%s:%s/%s uploaded' % (storage, content_type, template))
|
||||
|
||||
elif state == 'absent':
|
||||
try:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue