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

kubevirt_pvc: add 'wait' support #53692

Merged
merged 1 commit into from
Mar 13, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
66 changes: 65 additions & 1 deletion lib/ansible/modules/cloud/kubevirt/kubevirt_pvc.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,21 @@
- "This uses the DataVolume source syntax:
U(https://github.com/kubevirt/containerized-data-importer/blob/master/doc/datavolumes.md#https3registry-source)"
type: dict
wait:
description:
- "If set, this module will wait for the PVC to become bound and CDI (if enabled) to finish its operation
before returning."
- "Used only if I(state) set to C(present)."
- "Unless used in conjuction with I(cdi_source), this might result in a timeout, as clusters may be configured
mmazur marked this conversation as resolved.
Show resolved Hide resolved
to not bind PVCs until first usage."
default: false
type: bool
wait_timeout:
description:
- Specifies how much time in seconds to wait for PVC creation to complete if I(wait) option is enabled.
- Default value is reasonably high due to an expectation that CDI might take a while to finish its operation.
type: int
default: 300

extends_documentation_fragment:
- k8s_auth_options
Expand Down Expand Up @@ -277,10 +292,22 @@
'storage_class_name': {'type': 'str'},
'volume_mode': {'type': 'str'},
'volume_name': {'type': 'str'},
'cdi_source': {'type': 'dict'}
'cdi_source': {'type': 'dict'},
'wait': {
'type': 'bool',
'default': False
mmazur marked this conversation as resolved.
Show resolved Hide resolved
},
'wait_timeout': {
'type': 'int',
'default': 300
}
}


class CreatePVCFailed(Exception):
pass


class KubevirtPVC(KubernetesRawModule):
def __init__(self):
super(KubevirtPVC, self).__init__()
Expand All @@ -291,6 +318,12 @@ def argspec(self):
argument_spec.update(PVC_ARG_SPEC)
return argument_spec

@staticmethod
def fix_serialization(obj):
if obj and hasattr(obj, 'to_dict'):
return obj.to_dict()
return obj

def _parse_cdi_source(self, _cdi_src, metadata):
cdi_src = copy.deepcopy(_cdi_src)
annotations = metadata['annotations']
Expand Down Expand Up @@ -340,6 +373,35 @@ def _parse_cdi_source(self, _cdi_src, metadata):
if 'certConfigMap' in src_spec:
annotations['cdi.kubevirt.io/storage.import.certConfigMap'] = src_spec['certConfigMap']

def _wait_for_creation(self, resource, uid):
return_obj = None
desired_cdi_status = 'Succeeded'
use_cdi = True if self.params.get('cdi_source') else False
if use_cdi and 'upload' in self.params['cdi_source']:
desired_cdi_status = 'Running'

for event in resource.watch(namespace=self.namespace, timeout=self.params.get('wait_timeout')):
entity = event['object']
metadata = entity.metadata
if not hasattr(metadata, 'uid') or metadata.uid != uid:
continue
if entity.status.phase == 'Bound':
if use_cdi and hasattr(metadata, 'annotations'):
import_status = metadata.annotations.get('cdi.kubevirt.io/storage.pod.phase')
if import_status == desired_cdi_status:
return_obj = entity
break
else:
return_obj = entity
break
elif entity.status.phase == 'Failed':
raise CreatePVCFailed("PVC creation failed")
mmazur marked this conversation as resolved.
Show resolved Hide resolved

if not return_obj:
raise CreatePVCFailed("PVC creation timed out")
mmazur marked this conversation as resolved.
Show resolved Hide resolved

return self.fix_serialization(return_obj)

def execute_module(self):
KIND = 'PersistentVolumeClaim'
API = 'v1'
Expand Down Expand Up @@ -379,6 +441,8 @@ def execute_module(self):
resource = self.find_resource(KIND, API, fail=True)
definition = self.set_defaults(resource, definition)
result = self.perform_action(resource, definition)
if self.params.get('wait') and self.params.get('state') == 'present':
result['result'] = self._wait_for_creation(resource, result['result']['metadata']['uid'])

self.exit_json(**result)

Expand Down