[DRAFT] Operation variable structure and task dispatch
The current data structure that's being passed into the back-end is a bit too simple to be really useful. I think we should pass a single variable representing the operation, that contains a list of tasks, each with relevant UUIDs, etc.
operation:
name: <operation_name>
uuid: <UUID>
tasks:
<task1_name>:
role: <task1_role>
weight: <#>
vars:
<field1_name>: <field1_value>
<field2_name>: <field2_value>
<fieldN_name>: <fieldN_value>
uuid: <UUID>
<task1_name>:
...
<taskN_name>:
...
It'd then be pretty simple to iterate over this to make all tasks vars available to each other across the operation:
# main.yml
- name: Make variables passed-in from the Aegir front-end available to this operation's tasks.
include: variables.yml
vars:
task_name: "{{ task.name }}"
task_vars: "{{ task.vars }}"
loop: "{{ operation.tasks | dict2items }}"
loop_control:
loop_var: task
# variables.yml
- name: "Make variables from the {{ task_name }} task available to this operation's tasks."
set_fact: {"{{ item.key }}": "{{ item.value }}"}
loop: "{{ task_vars | dict2items }}"
We can dispatch each task using a similar loop. Tasks can now be grouped into logical roles, instead of requiring a 1:1 ratio of tasks to roles.
# tasks.yml
- name: Delegate to tasks in command/service roles (eg. git, nginx, mariadb)
include_role:
name: "{{ task.value.role }}"
tasks_from: "{{ task.key }}.yml"
public: yes
loop: "{{ operation.tasks | dict2items }}"
loop_control:
loop_var: task
This logic can all, itself, be contained in an aegir.operation
role. That would only require a single static playbook, rather than generating a new one with each operation.
Since we're down to a single (complex) variable, we could perhaps even pass it into the Ansible call. However, that'd presumably be exposed in the process list, so we should probably continue to generate temporary variables files. However, these should secured with strict file ownership/permissions, and garbage-collected immediately.