From 44c00b9ca417546b057266bfad5cd508a8112087 Mon Sep 17 00:00:00 2001 From: Dawid Deja Date: Wed, 3 Feb 2016 18:24:07 +0100 Subject: [PATCH] Separate geting flavors and filtering into separe tasks Also minimalize numbers of calls to nova API Signed-off-by: Dawid Deja --- README.rst | 7 +++-- evacuate_vm_action.py | 17 ------------- filter_vm_action.py | 48 +++++++++-------------------------- find_flavors_by_extra_spec.py | 32 +++++++++++++++++++++++ host-evacuate.yaml | 46 ++++++++++++++++++--------------- input.json | 5 +++- 6 files changed, 79 insertions(+), 76 deletions(-) delete mode 100644 evacuate_vm_action.py create mode 100644 find_flavors_by_extra_spec.py diff --git a/README.rst b/README.rst index 93c2f32..75f6763 100644 --- a/README.rst +++ b/README.rst @@ -18,7 +18,7 @@ Installation mistral.actions = … custom.filter_vm = filter_vm_action:FilterVmAction - custom.evacuate = evacuate_vm_action:EvacuateVmAction + custom.find_flavors = find_flavors_by_extra_spec:FindFlavorsByExtraSpecs to ``setup.cfg`` file under Mistral repository #. Run db-sync tool via either @@ -47,7 +47,10 @@ Installation "search_opts": { "host": "compute-hostanme" }, - "on_shared_storage": false + "on_shared_storage": false, + "flavor_extra_specs": { + "evacuation:evacuate": true + } } #. Trigger the action via: diff --git a/evacuate_vm_action.py b/evacuate_vm_action.py deleted file mode 100644 index 55bd1d4..0000000 --- a/evacuate_vm_action.py +++ /dev/null @@ -1,17 +0,0 @@ -from mistral.actions.openstack.actions import NovaAction -from mistral.workflow.utils import Result - - -class EvacuateVmAction(NovaAction): - - def __init__(self, uuid, on_shared_storage, evacuate): - self._uuid = uuid - self._on_shared_storage = on_shared_storage - self._evacuate = evacuate - - def run(self): - client = self._get_client() - - if self._evacuate: - client.servers.evacuate(self._uuid, - on_shared_storage=self._on_shared_storage) diff --git a/filter_vm_action.py b/filter_vm_action.py index e7a7510..0da3eff 100644 --- a/filter_vm_action.py +++ b/filter_vm_action.py @@ -4,52 +4,28 @@ FilterVmAction - custom action. Simple action for filtering VM on the presence of metadata/extra spec "evacuate" flag """ -from mistral.actions.openstack.actions import NovaAction -from mistral.workflow.utils import Result +from mistral.actions import base -class FilterVmException(Exception): - pass - - -class FilterVmAction(NovaAction): +class FilterVmAction(base.Action): """ Filter and return VMs whith the flag 'evacuate' either on vm metadtata or flavor extra spec. """ - def __init__(self, metadata, flavor, uuid): + def __init__(self, flavors, vms): """init.""" - self._metadata = metadata - self._flavor = flavor - self._uuid = uuid + self._flavors = flavors + self._vms = vms def run(self): """Entry point for the action execution.""" - client = self._get_client() - metadata = self._metadata + result = [] - if str(metadata.get('evacuate')).upper() == 'TRUE': - return Result(data={'evacuate': True, 'uuid': self._uuid}) - elif str(metadata.get('evacuate')).upper() == 'FALSE': - return Result(data={'evacuate': False, 'uuid': self._uuid}) + for vm in self._vms: + if str(vm['metadata'].get('evacuate')).upper() == 'TRUE'\ + or (str(vm['metadata'].get('evacuate')).upper() != 'FALSE' + and vm['flavor']['id'] in self._flavors): + result.append(vm['id']) - # Ether is no metadata for vm - check flavor. - try: - # Maybe this should be done in different action - # only once per whole workflow. - # In case there is ~100 VMs to evacuate, there will be - # the same amount of calls to nova API. - flavor = filter( - lambda f: f.id == self._flavor, - client.flavors.list() - )[0] - except IndexError: - raise FilterVmException('Flavor not found') - - evacuate = flavor.get_keys().get('evacuation:evacuate') - - if str(evacuate).upper() == 'TRUE': - return Result(data={'evacuate': True, 'uuid': self._uuid}) - - return Result(data={'evacuate': False, 'uuid': self._uuid}) + return result \ No newline at end of file diff --git a/find_flavors_by_extra_spec.py b/find_flavors_by_extra_spec.py new file mode 100644 index 0000000..e65a488 --- /dev/null +++ b/find_flavors_by_extra_spec.py @@ -0,0 +1,32 @@ +""" +FindFlavorsByExtraSpecs - custom action. + +It works pretty similar to nova.flavors_findall, but it looks for items in +flavors extra spec +""" + +from mistral.actions.openstack.actions import NovaAction + + +class FindFlavorsByExtraSpecs(NovaAction): + + def __init__(self, extra_specs): + if type(extra_specs) is dict: + self._extra_specs = extra_specs + else: + raise TypeError("Extra spec must be a dictionary") + + def run(self): + client = self._get_client() + flavors = client.flavors.list() + result = [] + + for flavor in flavors: + flavor_extra_specs = flavor.get_keys().items() + if all( + item in flavor_extra_specs + for item in self._extra_specs.items() + ): + result.append(flavor.id) + + return result \ No newline at end of file diff --git a/host-evacuate.yaml b/host-evacuate.yaml index da22dab..2d78cbe 100644 --- a/host-evacuate.yaml +++ b/host-evacuate.yaml @@ -2,27 +2,33 @@ version: '2.0' host-evacuate: - description: Evacuate VMs from given host - type: direct + description: Evacuate VMs from given host + type: direct + input: + - search_opts + - on_shared_storage + - flavor_extra_specs - input: - - search_opts - - on_shared_storage + tasks: + list_vms: + action: nova.servers_list search_opts=<% $.search_opts %> + publish: + vms: <% $.list_vms %> + on-success: filter_vms - tasks: - list_vms: - action: nova.servers_list search_opts=<% $.search_opts %> - publish: - vms: <% $.list_vms %> - on-success: filter_vms + list_flavors: + action: custom.find_flavors extra_specs=<% $.flavor_extra_specs %> + publish: + flavors: <% $.list_flavors %> + on-success: filter_vms - filter_vms: - with-items: vm in <% $.vms %> - action: custom.filter flavor=<% $.vm.flavor.id %> metadata=<% $.vm.metadata %> uuid=<% $.vm.id %> - publish: - filtered_vms: <% $.filter_vms %> - on-success: evacuate_vms + filter_vms: + join: all + action: custom.filter flavors=<% $.flavors %> vms=<% $.vms %> + publish: + filtered_vms: <% $.filter_vms %> + on-success: evacuate_vms - evacuate_vms: - with-items: vm in <% $.filtered_vms %> - action: custom.evacuate uuid=<% $.vm.uuid %> evacuate=<% $.vm.evacuate %> on_shared_storage=<% $.on_shared_storage %> + evacuate_vms: + with-items: vm in <% $.filtered_vms %> + action: nova.servers_evacuate server=<% $.vm %> on_shared_storage=<% $.on_shared_storage %> diff --git a/input.json b/input.json index 7cf86dc..3558c0f 100644 --- a/input.json +++ b/input.json @@ -2,5 +2,8 @@ "search_opts": { "host": "compute1" }, - "on_shared_storage": false + "on_shared_storage": false, + "flavor_extra_specs": { + "evacuation:evacuate": true + } }