1
0
mirror of https://github.com/gryf/mistral-evacuate.git synced 2026-02-07 16:55:52 +01: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 =
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:

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

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'
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 %>

View File

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