Skip to main content

Pulp plugin for managing task schedules via CRUD API

Project description

pulp-workflow

Warning: This is a community plugin and is not officially supported. Scheduling tasks incorrectly can cause serious issues in your Pulp instance. Always test in a development environment first before applying changes to production.

A Pulp plugin that introduces the Workflow model. Workflows build on top of tasks in Pulp allowing users to:

  • Schedule tasks to run at any given time
  • Run sequences of tasks in a specific order
  • Set up callback services to run on workflow lifecycle events (e.g. running, completed, failed, canceled, finished)

A Workflow owns one or more WorkflowTask rows. Each task records the task_name, task_args, task_kwargs, and any reserved_resources to use when dispatching it. Workflows are immutable after creation: to change a workflow, cancel it (if it has not yet started) and create a new one.

Endpoints

Method URL Description
GET /pulp/api/v3/workflow/workflows/ List workflows
POST /pulp/api/v3/workflow/workflows/ Create a workflow (with tasks)
GET /pulp/api/v3/workflow/workflows/<pk>/ Retrieve a workflow
PATCH /pulp/api/v3/workflow/workflows/<pk>/ Cancel a workflow (body: {"state": "canceled"}). Works whether the workflow is waiting or running; returns 409 only if the workflow is already in a terminal state. Only "canceled" is accepted as the target state.

How execution works

When a workflow is created, TaskSchedule dispatches a single execute_workflow task. Rather than looping inside one long-running task (which would pin a worker for the entire duration of the pipeline), execute_workflow runs one step at a time and re-dispatches itself for the next step. Each invocation either transitions the workflow to running (on the first step) or inspects the previous step's child task and fails the workflow if it did not complete. If there are no more WorkflowTask rows at the next index, the workflow is marked completed.

Sequencing relies on pulpcore's tasking locks rather than polling. Every invocation dispatches the child task with a shared lock on the workflow's resource string (pulp_workflow:workflow:<pk>) and then dispatches the next execute_workflow continuation with an exclusive lock on the same resource. Because the exclusive lock cannot be granted while the shared lock is held, the continuation is guaranteed to wait until the child task ends — without blocking a worker on a polling loop. This keeps concurrent workflows from deadlocking when their count meets or exceeds the worker count.

The diagram below shows two consecutive tasks. S denotes a shared lock and X denotes an exclusive lock on the workflow resource.

sequenceDiagram
    autonumber
    participant TaskSchedule
    participant EW0 as execute_workflow(0)
    participant T0 as Child Task 0
    participant EW1 as execute_workflow(1)
    participant T1 as Child Task 1
    participant EW2 as execute_workflow(2)

    TaskSchedule->>EW0: dispatch (X on workflow)
    activate EW0
    EW0->>EW0: state = RUNNING
    EW0->>T0: dispatch (S on workflow)
    EW0->>EW1: dispatch (X on workflow) — queued
    deactivate EW0

    activate T0
    Note over EW1: blocked: X waits for S to release
    T0-->>T0: run task body
    T0->>T0: state = COMPLETED
    deactivate T0

    activate EW1
    EW1->>EW1: verify Task 0 COMPLETED
    EW1->>T1: dispatch (S on workflow)
    EW1->>EW2: dispatch (X on workflow) — queued
    deactivate EW1

    activate T1
    Note over EW2: blocked until T1 finishes
    T1-->>T1: run task body
    T1->>T1: state = COMPLETED
    deactivate T1

    activate EW2
    EW2->>EW2: verify Task 1 COMPLETED
    EW2->>EW2: no task at index 2 → state = COMPLETED
    deactivate EW2

If any child task ends in a non-completed state, or if dispatching a child raises, the next execute_workflow invocation records the failure on the workflow (error field, including the child's traceback when available), transitions the workflow to failed, and stops the chain.

Task groups

Every workflow is backed by a pulpcore TaskGroup. On creation, the workflow allocates a TaskGroup(description="Workflow: <name>") in the workflow's domain and links it via the task_group field on the Workflow resource. The dispatched child tasks and the execute_workflow continuations are members of that group. The initial execute_workflow task itself is dispatched by the TaskSchedule created at workflow-create time and is not a member of the group. Membership means:

  • GET /pulp/api/v3/task-groups/<pk>/ lists every task the workflow has spawned in one place.
  • GET /pulp/api/v3/tasks/?task_group=<pk> filters tasks to that workflow.
  • Existing client tooling (monitor_task_group, TaskGroupOperationResponse) works against workflows the same way it does for replication and pulp-import.
  • A child task can discover that it is part of a workflow via TaskGroup.current() without pulp_workflow having to plumb that context through itself.

The group's all_tasks_dispatched flag is False while the workflow is running and flipped to True exactly once the workflow reaches a terminal state (completed, failed, or canceled).

Cancellation

A workflow can be canceled either by PATCHing the workflow with {"state": "canceled"} or by canceling its backing TaskGroup directly. Both paths converge on the same terminal state: Workflow.state = canceled, finished_at set, TaskGroup.all_tasks_dispatched = True, and any in-flight or queued child tasks (including the execute_workflow continuation) canceled. PATCH on an already-terminal workflow returns 409.

The TaskGroup cancel path is bridged back to the workflow row via a post_save receiver on TaskGroup, so cancellation initiated outside the workflow viewset still terminates the Workflow correctly.

flowchart TD
    A[PATCH /pulp/api/v3/workflow/workflows/&lt;pk&gt;/<br/>state: canceled] --> B[WorkflowViewSet]
    B --> C[Workflow.state = canceled<br/>finished_at = now]
    C --> D[cancel_task_group<br/>on commit]

    E[POST /pulp/api/v3/task-groups/&lt;pk&gt;/cancel/] --> F[pulpcore cancels<br/>group's tasks]
    F --> G[TaskGroup.all_tasks_dispatched = True<br/>TaskGroup.save]

    D --> G
    G --> H[post_save receiver<br/>on TaskGroup]
    H --> I{Workflow already<br/>terminal?}
    I -- yes --> J[no-op]
    I -- no --> K[Workflow.state = canceled<br/>finished_at = now]

    classDef terminal fill:#e8f5e9,stroke:#2e7d32;
    class C,K terminal;

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pulp_workflow-0.1.1.tar.gz (36.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pulp_workflow-0.1.1-py3-none-any.whl (41.3 kB view details)

Uploaded Python 3

File details

Details for the file pulp_workflow-0.1.1.tar.gz.

File metadata

  • Download URL: pulp_workflow-0.1.1.tar.gz
  • Upload date:
  • Size: 36.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pulp_workflow-0.1.1.tar.gz
Algorithm Hash digest
SHA256 d840522ca335b229364e146ba19d06b0781640a2f9d47c55afe144697bc186e1
MD5 f4970882a7d407ab051327104e8fa3fc
BLAKE2b-256 6dc02182d7771a5ff88b711ef11018d6104fae0b893a4a9a4a7b170c3b70da47

See more details on using hashes here.

Provenance

The following attestation bundles were made for pulp_workflow-0.1.1.tar.gz:

Publisher: publish.yml on daviddavis/pulp_workflow

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pulp_workflow-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: pulp_workflow-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 41.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pulp_workflow-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d058a58257a87040bb94f7984cb2ea815f28e5f867e3682bd3c71340b19036af
MD5 1c2fdb8ede5f2ac272cbe62d5c3867e7
BLAKE2b-256 369207eae624dc8d53541d6408d5eb4fbba26e72a8872f8d4b89b36f0b252336

See more details on using hashes here.

Provenance

The following attestation bundles were made for pulp_workflow-0.1.1-py3-none-any.whl:

Publisher: publish.yml on daviddavis/pulp_workflow

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page