Craton Workflow Engine

Registered by Sulochan Acharya

Workflows are integral part of Craton. It allows operators to register pre-defined task(s) and run them on a given inventory. Tasks can be combined together to form a job. Workflow engine ensures users have proper permission to run a given task. Admin users can make a task public or make it available to a given role.

Workflow allows users to run a given task/job against a host to do many operational tasks. Imagine a workflow to be something like so:

Given a condition where operator needs to do a disruptive maintenance on a host, a craton workflow could be written to do the following in an automated fashion:

1. Disable compute in nova
2. Live-migrate all vm's from the host to another
3. Run some pre-patch/reboot checks
5. Disable monitoring
4. Patch the host
5. Reboot the host
6. Run post patch/reboot checks
7. Enable monitoring
8. Enable compute

This is one example where each step is a registered task and could have been run as a singleton.

=========================================================================
One implementation of workflow engine that uses Docker
=========================================================================
Uses:
Docker Engine
docker-py

Might Use:
Docker Registry
Taskflow

Language Supported:
Initially python 2/3

1. User -> Create Individual tasks. Task is one unit of work. Example task: Run ONE ansible playbook. Run a command. Task can be executed on one or more hosts. What hosts to execute a task on is provided in the forma on an inventory to the task.

2. User -> Creates Workflow |-Task1
                                              |-Task2
                                              |-TaskN

3. User -> Executes a workflow on some inventory.

User -> API -> Execute WF -> Wofkflow [Docker Swarm] -> [ Execute Task 1 in container]
                                                                                                     \ if successful
                                                                                           -> [Execute Task 2 in container]
                                                                                                     \ if successful
                                                                                            -> [Execute Task 3 in container]

User defines Tasks:
---------------------------
In github or in local dir:

   /craton_task1
    |-> __init__.py
    |-> task1.py
    |-> task_uti.py
    |-> requirements.txt
    |-> Dockerfile

When the task is created in Craton though the api (using cli), we build the docker image and sync it to all the swarm cluster nodes. Users can see that the task is ready to be used in a workflow when the status filed in task is Ready. This means the images was successfully build and is ready to be consumed. Users can locally test this in their laptop before creating the task.

$ craton task-show 12345
---------------------------------------------------------------------------------------
| id | name | location | ..... | Status |
---------------------------------------------------------------------------------------
| 12345 | task1 | github.com/sulochan/craton_tasks | ..... | Ready |
---------------------------------------------------------------------------------------

Once the task is ready, it can be a part of a workflow Definition. When a user executes a workflow, the task container is run with the inventory data payload and any other payload defined in the workflow variables. This basically translates to

docker run -t task1:latest python /craton/task1.py '{"a":"b" ...}'

What command is called on the particular task is defined during task creation. The dockerfile is responsible to putting things and installing the correct modules required by the task. For example for task1 the dockerfile looks like so:

$ cat Dockerfile
from alpine:latest
RUN apk add --no-cache bash linux-headers build-base git python3 python3-dev
ADD https://bootstrap.pypa.io/get-pip.py /root/get-pip.py
RUN python3.5 /root/get-pip.py
Add . /craton
RUN pip install -r /craton/requirements.txt

Hence, the calling command become /craton/task1.py '{"a":"b" ...}' where the variables part is passed during the execution of the task by craton workflow engine.

If the task is successful, the next task (if one exists) is called and so on.

Things that need discussion/finalising:
--------------------------------------
1. Allow users to use craton client to build images locally and push to central craton docker registry. This assumes we use local registry as a part of our service process.

2. How to handle per task logs.
3. How long to keep per task container after execution.
4. Do we support more than python ?

Blueprint information

Status:
Not started
Approver:
None
Priority:
Undefined
Drafter:
Sulochan Acharya
Direction:
Needs approval
Assignee:
Sulochan Acharya
Definition:
New
Series goal:
None
Implementation:
Unknown
Milestone target:
milestone icon newton-1

Related branches

Sprints

Whiteboard

Gerrit topic: https://review.openstack.org/#q,topic:bp/workflow,n,z

Addressed by: https://review.openstack.org/355938
    Craton workflow processes

Gerrit topic: https://review.openstack.org/#q,topic:bp/craton-workflow-engine,n,z

Addressed by: https://review.openstack.org/421337
    Add spec for workflow engine

(?)

Work Items

Work items:
Create Task/Job models for db : TODO
Create API endpoints for workflows: TODO
Create Workflow logic to be able to run any task as a workflow: TODO
Create API endpoint to allow GET on submitted workflow to view result: TODO
Add Retry logic: TODO
Schedule against a task graph: TODO

Dependency tree

* Blueprints in grey have been implemented.

This blueprint contains Public information 
Everyone can see this information.