1
0
mirror of https://github.com/gryf/mistral-evacuate.git synced 2026-04-02 09:13:32 +02:00

Separate geting flavors and filtering into separe tasks

Also minimalize numbers of calls to nova API

Signed-off-by: Dawid Deja <dawid.deja@intel.com>
This commit is contained in:
Dawid Deja
2016-02-03 18:24:07 +01:00
parent bcafa3f466
commit 44c00b9ca4
6 changed files with 79 additions and 76 deletions

View File

@@ -18,7 +18,7 @@ Installation
mistral.actions = mistral.actions =
custom.filter_vm = filter_vm_action:FilterVmAction 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 to ``setup.cfg`` file under Mistral repository
#. Run db-sync tool via either #. Run db-sync tool via either
@@ -47,7 +47,10 @@ Installation
"search_opts": { "search_opts": {
"host": "compute-hostanme" "host": "compute-hostanme"
}, },
"on_shared_storage": false "on_shared_storage": false,
"flavor_extra_specs": {
"evacuation:evacuate": true
}
} }
#. Trigger the action via: #. Trigger the action via:

View File

@@ -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)

View File

@@ -4,52 +4,28 @@ FilterVmAction - custom action.
Simple action for filtering VM on the presence of metadata/extra spec Simple action for filtering VM on the presence of metadata/extra spec
"evacuate" flag "evacuate" flag
""" """
from mistral.actions.openstack.actions import NovaAction from mistral.actions import base
from mistral.workflow.utils import Result
class FilterVmException(Exception): class FilterVmAction(base.Action):
pass
class FilterVmAction(NovaAction):
""" """
Filter and return VMs whith the flag 'evacuate' either on vm metadtata Filter and return VMs whith the flag 'evacuate' either on vm metadtata
or flavor extra spec. or flavor extra spec.
""" """
def __init__(self, metadata, flavor, uuid): def __init__(self, flavors, vms):
"""init.""" """init."""
self._metadata = metadata self._flavors = flavors
self._flavor = flavor self._vms = vms
self._uuid = uuid
def run(self): def run(self):
"""Entry point for the action execution.""" """Entry point for the action execution."""
client = self._get_client() result = []
metadata = self._metadata
if str(metadata.get('evacuate')).upper() == 'TRUE': for vm in self._vms:
return Result(data={'evacuate': True, 'uuid': self._uuid}) if str(vm['metadata'].get('evacuate')).upper() == 'TRUE'\
elif str(metadata.get('evacuate')).upper() == 'FALSE': or (str(vm['metadata'].get('evacuate')).upper() != 'FALSE'
return Result(data={'evacuate': False, 'uuid': self._uuid}) and vm['flavor']['id'] in self._flavors):
result.append(vm['id'])
# Ether is no metadata for vm - check flavor. return result
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})

View File

@@ -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

View File

@@ -2,27 +2,33 @@
version: '2.0' version: '2.0'
host-evacuate: host-evacuate:
description: Evacuate VMs from given host description: Evacuate VMs from given host
type: direct type: direct
input:
- search_opts
- on_shared_storage
- flavor_extra_specs
input: tasks:
- search_opts list_vms:
- on_shared_storage action: nova.servers_list search_opts=<% $.search_opts %>
publish:
vms: <% $.list_vms %>
on-success: filter_vms
tasks: list_flavors:
list_vms: action: custom.find_flavors extra_specs=<% $.flavor_extra_specs %>
action: nova.servers_list search_opts=<% $.search_opts %> publish:
publish: flavors: <% $.list_flavors %>
vms: <% $.list_vms %> on-success: filter_vms
on-success: filter_vms
filter_vms: filter_vms:
with-items: vm in <% $.vms %> join: all
action: custom.filter flavor=<% $.vm.flavor.id %> metadata=<% $.vm.metadata %> uuid=<% $.vm.id %> action: custom.filter flavors=<% $.flavors %> vms=<% $.vms %>
publish: publish:
filtered_vms: <% $.filter_vms %> filtered_vms: <% $.filter_vms %>
on-success: evacuate_vms on-success: evacuate_vms
evacuate_vms: evacuate_vms:
with-items: vm in <% $.filtered_vms %> with-items: vm in <% $.filtered_vms %>
action: custom.evacuate uuid=<% $.vm.uuid %> evacuate=<% $.vm.evacuate %> on_shared_storage=<% $.on_shared_storage %> action: nova.servers_evacuate server=<% $.vm %> on_shared_storage=<% $.on_shared_storage %>

View File

@@ -2,5 +2,8 @@
"search_opts": { "search_opts": {
"host": "compute1" "host": "compute1"
}, },
"on_shared_storage": false "on_shared_storage": false,
"flavor_extra_specs": {
"evacuation:evacuate": true
}
} }