one_image: Add image creation and timeout (#9075)

* Add creation one_image

* Add CHANGELOG

* PR fix docs

* Add doc line for create
pull/9098/head
alexander 2024-11-03 13:25:39 +03:00 committed by GitHub
parent 2429e228a4
commit cecaa1840d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 124 additions and 48 deletions

View File

@ -0,0 +1,3 @@
minor_changes:
- one_image - add ``create``, ``template`` and ``datastore_id`` arguments for image creation (https://github.com/ansible-collections/community.general/pull/9075).
- one_image - add ``wait_timeout`` argument for adjustable timeouts (https://github.com/ansible-collections/community.general/pull/9075).

View File

@ -32,13 +32,14 @@ options:
name: name:
description: description:
- A O(name) of the image you would like to manage. - A O(name) of the image you would like to manage.
- Required if O(create=true).
type: str type: str
state: state:
description: description:
- V(present) - state that is used to manage the image - V(present) - state that is used to manage the image.
- V(absent) - delete the image - V(absent) - delete the image.
- V(cloned) - clone the image - V(cloned) - clone the image.
- V(renamed) - rename the image to the O(new_name) - V(renamed) - rename the image to the O(new_name).
choices: ["present", "absent", "cloned", "renamed"] choices: ["present", "absent", "cloned", "renamed"]
default: present default: present
type: str type: str
@ -56,6 +57,28 @@ options:
- Whether the image should be persistent or non-persistent. - Whether the image should be persistent or non-persistent.
type: bool type: bool
version_added: 9.5.0 version_added: 9.5.0
create:
description:
- Whether the image should be created if not present.
- This is ignored if O(state=absent).
type: bool
version_added: 10.0.0
template:
description:
- Use with O(create=true) to specify image template.
type: str
version_added: 10.0.0
datastore_id:
description:
- Use with O(create=true) to specify datastore for image.
type: int
version_added: 10.0.0
wait_timeout:
description:
- Seconds to wait until image is ready, deleted or cloned.
type: int
default: 60
version_added: 10.0.0
author: author:
- "Milan Ilic (@ilicmilan)" - "Milan Ilic (@ilicmilan)"
''' '''
@ -102,6 +125,35 @@ EXAMPLES = '''
community.general.one_image: community.general.one_image:
id: '{{ result.id }}' id: '{{ result.id }}'
state: absent state: absent
- name: Make sure IMAGE is present
community.general.one_image:
name: myyy-image
state: present
create: true
datastore_id: 100
template: |
PATH = "/var/tmp/image"
TYPE = "OS"
SIZE = 20512
FORMAT = "qcow2"
PERSISTENT = "Yes"
DEV_PREFIX = "vd"
- name: Make sure IMAGE is present with a longer timeout
community.general.one_image:
name: big-image
state: present
create: true
datastore_id: 100
wait_timeout: 900
template: |
PATH = "https://192.0.2.200/repo/tipa_image.raw"
TYPE = "OS"
SIZE = 82048
FORMAT = "raw"
PERSISTENT = "Yes"
DEV_PREFIX = "vd"
''' '''
RETURN = ''' RETURN = '''
@ -328,15 +380,20 @@ IMAGE_STATES = ['INIT', 'READY', 'USED', 'DISABLED', 'LOCKED', 'ERROR', 'CLONE',
class ImageModule(OpenNebulaModule): class ImageModule(OpenNebulaModule):
def __init__(self): def __init__(self):
argument_spec = dict( argument_spec = dict(
id=dict(type='int', required=False), id=dict(type='int'),
name=dict(type='str', required=False), name=dict(type='str'),
state=dict(type='str', choices=['present', 'absent', 'cloned', 'renamed'], default='present'), state=dict(type='str', choices=['present', 'absent', 'cloned', 'renamed'], default='present'),
enabled=dict(type='bool', required=False), enabled=dict(type='bool'),
new_name=dict(type='str', required=False), new_name=dict(type='str'),
persistent=dict(type='bool', required=False), persistent=dict(type='bool'),
create=dict(type='bool'),
template=dict(type='str'),
datastore_id=dict(type='int'),
wait_timeout=dict(type='int', default=60),
) )
required_if = [ required_if = [
['state', 'renamed', ['id']] ['state', 'renamed', ['id']],
['create', True, ['template', 'datastore_id', 'name']],
] ]
mutually_exclusive = [ mutually_exclusive = [
['id', 'name'], ['id', 'name'],
@ -356,26 +413,32 @@ class ImageModule(OpenNebulaModule):
enabled = params.get('enabled') enabled = params.get('enabled')
new_name = params.get('new_name') new_name = params.get('new_name')
persistent = params.get('persistent') persistent = params.get('persistent')
create = params.get('create')
template = params.get('template')
datastore_id = params.get('datastore_id')
wait_timeout = params.get('wait_timeout')
self.result = {} self.result = {}
image = self.get_image_instance(id, name) image = self.get_image_instance(id, name)
if not image and desired_state != 'absent': if not image and desired_state != 'absent':
if create:
self.result = self.create_image(name, template, datastore_id, wait_timeout)
# Using 'if id:' doesn't work properly when id=0 # Using 'if id:' doesn't work properly when id=0
if id is not None: elif id is not None:
module.fail_json(msg="There is no image with id=" + str(id)) module.fail_json(msg="There is no image with id=" + str(id))
elif name is not None: elif name is not None:
module.fail_json(msg="There is no image with name=" + name) module.fail_json(msg="There is no image with name=" + name)
if desired_state == 'absent': if desired_state == 'absent':
self.result = self.delete_image(image) self.result = self.delete_image(image, wait_timeout)
else: else:
if persistent is not None: if persistent is not None:
self.result = self.change_persistence(image, persistent) self.result = self.change_persistence(image, persistent)
if enabled is not None: if enabled is not None:
self.result = self.enable_image(image, enabled) self.result = self.enable_image(image, enabled)
if desired_state == "cloned": if desired_state == "cloned":
self.result = self.clone_image(image, new_name) self.result = self.clone_image(image, new_name, wait_timeout)
elif desired_state == "renamed": elif desired_state == "renamed":
self.result = self.rename_image(image, new_name) self.result = self.rename_image(image, new_name)
@ -404,6 +467,16 @@ class ImageModule(OpenNebulaModule):
else: else:
return self.get_image_by_name(requested_name) return self.get_image_by_name(requested_name)
def create_image(self, image_name, template, datastore_id, wait_timeout):
if not self.module.check_mode:
image_id = self.one.image.allocate("NAME = \"" + image_name + "\"\n" + template, datastore_id)
self.wait_for_ready(image_id, wait_timeout)
image = self.get_image_by_id(image_id)
result = self.get_image_info(image)
result['changed'] = True
return result
def wait_for_ready(self, image_id, wait_timeout=60): def wait_for_ready(self, image_id, wait_timeout=60):
import time import time
start_time = time.time() start_time = time.time()
@ -491,7 +564,7 @@ class ImageModule(OpenNebulaModule):
return result return result
def clone_image(self, image, new_name): def clone_image(self, image, new_name, wait_timeout):
if new_name is None: if new_name is None:
new_name = "Copy of " + image.NAME new_name = "Copy of " + image.NAME
@ -506,7 +579,7 @@ class ImageModule(OpenNebulaModule):
if not self.module.check_mode: if not self.module.check_mode:
new_id = self.one.image.clone(image.ID, new_name) new_id = self.one.image.clone(image.ID, new_name)
self.wait_for_ready(new_id) self.wait_for_ready(new_id, wait_timeout)
image = self.one.image.info(new_id) image = self.one.image.info(new_id)
result = self.get_image_info(image) result = self.get_image_info(image)
@ -534,7 +607,7 @@ class ImageModule(OpenNebulaModule):
result['changed'] = True result['changed'] = True
return result return result
def delete_image(self, image): def delete_image(self, image, wait_timeout):
if not image: if not image:
return {'changed': False} return {'changed': False}
@ -543,7 +616,7 @@ class ImageModule(OpenNebulaModule):
if not self.module.check_mode: if not self.module.check_mode:
self.one.image.delete(image.ID) self.one.image.delete(image.ID)
self.wait_for_delete(image.ID) self.wait_for_delete(image.ID, wait_timeout)
return {'changed': True} return {'changed': True}