forked from intel/dffml
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
operations: deploy: Continuous Delivery of DataFlows usage example
- ffmpeg example operations - Deploy operations - Continuous Delivery of DataFlows usage example Fixes: intel#608 Fixes: intel#532 Fixes: intel#534 Signed-off-by: John Andersen <[email protected]>
- Loading branch information
Showing
70 changed files
with
1,647 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,3 +11,4 @@ The following are some example use cases of DFFML. | |
dataflows | ||
mnist | ||
io | ||
webhook/index |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
.. _usage_ffmpeg_deploy: | ||
|
||
Deploying with the HTTP Service | ||
=============================== | ||
|
||
In this tutorial we will deploy a dataflow(ffmpeg dataflow) which converts a video to gif over an HTTP service. We'll | ||
also see how to deploy the same in a docker container. Finally in :ref:`usage_ffmpeg_deploy_serve` | ||
we'll setup another HTTP service which waits on GitHub webhooks to rebuilt and deploy the ffmpeg dataflow. | ||
|
||
.. note:: | ||
|
||
All the code for this example is located under the | ||
`examples/ffmpeg <https://github.com/intel/dffml/blob/master/examples/ffmpeg/>`_ | ||
directory of the DFFML source code. | ||
|
||
We'll be using additional plugins from dffml, ``dffml-yaml-config`` and ``dffml-http-service``. | ||
|
||
.. code-block:: console | ||
$ pip install dffml-yaml-config dffml-http-service | ||
Create the Package | ||
------------------ | ||
|
||
To create a new operation we first create a new Python package. DFFML has a script to do it for you. | ||
|
||
.. code-block:: console | ||
$ dffml service dev create operations ffmpeg | ||
$ cd ffmpeg | ||
Write operations and definitions to convert videos files to gif by calling | ||
``ffmpeg`` (Make sure you `download and install <https://www.ffmpeg.org/download.html>`_ it). | ||
The operation accepts bytes (of the video), converts it to gif and outputs it as bytes. | ||
We will start writing our operation in ``./ffmpeg/operations.py`` | ||
|
||
**ffmpeg/operations.py** | ||
|
||
.. literalinclude:: /../examples/ffmpeg/ffmpeg/operations.py | ||
|
||
Add the operation to ``ffmpeg/setup.py`` | ||
|
||
.. code-block:: python | ||
common.KWARGS["entry_points"] = { | ||
"dffml.operation": [ | ||
f"convert_to_gif = {common.IMPORT_NAME}.operations:convert_to_gif" | ||
] | ||
} | ||
Install the package | ||
|
||
.. code-block:: console | ||
$ pip install -e . | ||
Dataflow and Config files | ||
------------------------- | ||
|
||
**ffmpeg/dataflow.py** | ||
|
||
.. literalinclude:: /../examples/ffmpeg/ffmpeg/dataflow.py | ||
|
||
.. code-block:: console | ||
$ mkdir -p deploy/mc/http deploy/df | ||
$ dffml service dev export -config yaml ffmpeg.dataflow:DATAFLOW > deploy/df/ffmpeg.yaml | ||
Create the config file for the HTTP service | ||
in ``deploy/mc/http/ffmpeg.yaml`` | ||
|
||
.. code-block:: console | ||
$ cat > ./deploy/mc/http/ffmpeg.yaml <<EOF | ||
path: /ffmpeg | ||
input_mode: bytes:input_file | ||
output_mode: bytes:image/gif:post_input.output_file | ||
EOF | ||
- ``input_mode`` | ||
|
||
- ``bytes:input_file`` | ||
|
||
- We want the input from the request to be treated as bytes with definition ``input_file``. | ||
|
||
- ``output_mode`` | ||
|
||
- ``bytes:image/gif:post_input.output_file`` | ||
|
||
- We want the response (content_type = image/gif) to be bytes taken from ``results["post_input"]["output_file"]``, | ||
where ``results`` is the output of the dataflow. | ||
|
||
For more details see `HttpChannelConfig <../../plugins/service/http/dataflow.html#HttpChannelConfig>`__ . | ||
|
||
.. _usage_ffmpeg_deploy_serve: | ||
|
||
Serving the DataFlow | ||
-------------------- | ||
|
||
Serving the dataflow on port 8080 | ||
|
||
.. code-block:: console | ||
$ dffml service http server -insecure -mc-config deploy -port 8080 | ||
.. warning:: | ||
|
||
The ``-insecure`` flag is only being used here to speed up this | ||
tutorial. See documentation on HTTP API | ||
:doc:`/plugins/service/http/security` for more information. | ||
|
||
Now from another terminal, we can send post requests to the dataflow running at this port. | ||
|
||
.. code-block:: console | ||
$ curl -v --request POST --data-binary @input.mp4 http://localhost:8080/ffmpeg -o output.gif | ||
You should replace ``input.mp4`` with path to your video file and ``output.gif`` to where you want the converted gif | ||
to be output to. An example video is available `here <https://github.com/intel/dffml/raw/master/examples/ffmpeg/tests/input.mp4>`_ . | ||
|
||
Deploying via container | ||
======================= | ||
|
||
A ``Dockerfile`` is already generated in ffmpeg folder. We need to modify it to include ``ffmpeg``. | ||
|
||
**Dockerfile** | ||
|
||
.. literalinclude:: /../examples/ffmpeg/Dockerfile | ||
|
||
.. note:: | ||
|
||
The run command in the comment section of the Dockerfile will be used to execute | ||
the container after receving webhooks, so make sure you change it to your usecase. | ||
|
||
For this tutorial we will change it to | ||
|
||
.. code-block:: Dockerfile | ||
# docker run --rm -ti -p 8080:8080 $USER/ffmpeg -mc-config deploy -insecure -log debug | ||
.. note:: | ||
|
||
The image built after pulling the contaier will be taged ``USERNAME/REPONAME``, where USERNAME and REPONAME | ||
are gathered from the github html url, received in the webhook. | ||
|
||
We can run the container and sent a post request to verify that the container is working. | ||
|
||
.. code-block:: console | ||
$ docker build -t $USER/ffmpeg . | ||
$ docker run --rm -ti -p 8080:8080 $USER/ffmpeg -mc-config deploy -insecure -log debug | ||
Now in another terminal | ||
|
||
.. code-block:: console | ||
$ curl -v --request POST --data-binary @input.mp4 http://localhost:8080/ffmpeg -o output.gif | ||
Now in :ref:`usage_webhook` we'll setup this container to be automatically redeployed | ||
whenever we push to the Git repo containing this code. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
Continuous Deployment of DataFlows | ||
================================== | ||
|
||
This example shows how to deploy your dataflow and to set it up so that it gets redployed | ||
on receiving webhooks from GitHub. | ||
|
||
.. toctree:: | ||
:maxdepth: 2 | ||
:caption: Contents: | ||
|
||
deploy | ||
webhook |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
.. _usage_webhook: | ||
|
||
Redeploying on receving GitHub webhook | ||
====================================== | ||
|
||
We'll move ``ffmpeg`` to a GitHub repo, and set up a webhook DataFlow such that whenever | ||
we push to the default branch, the new version is pulled and its docker container is built and run. | ||
|
||
Webhook Dataflow | ||
---------------- | ||
|
||
We'll be using operations from ``dffml-operations-deploy``, ``dffml-feature-git``, ``dffml-config-yaml``. | ||
|
||
.. code-block:: console | ||
$ pip install dffml-operations-deploy dffml-feature-git dffml-config-yaml | ||
Setup a http server in ``ffmpeg/deploy/webhook``, to receive webhook and redploy ffmpeg | ||
|
||
.. code-block:: console | ||
$ mkdir -p deploy/webhook/df deploy/webhook/mc/http | ||
$ cat > /tmp/operations <<EOF | ||
get_url_from_payload | ||
clone_git_repo | ||
check_if_default_branch | ||
get_image_tag | ||
get_running_containers | ||
get_status_running_containers | ||
parse_docker_commands | ||
docker_build_image | ||
restart_running_containers | ||
cleanup_git_repo | ||
EOF | ||
$ dffml dataflow create -config yaml $(cat /tmp/operations) > deploy/webhook/df/webhook.yaml | ||
Config | ||
|
||
**deploy/webhook/mc/http/webhook.yaml** | ||
|
||
.. code-block:: console | ||
$ cat > ./deploy/webhook/mc/http/webhook.yaml <<EOF | ||
path: /webhook/github | ||
output_mode: json | ||
input_mode: json:git_payload | ||
EOF | ||
Note that the input_mode is ``json:git_payload``, this means that inputs from post request will | ||
be parsed as JSON and then forwarded to dataflow as the ``git_payload`` definition.. | ||
|
||
Deploy it in port 8081 as 8080 is being used by ffmpeg http service | ||
|
||
.. code-block:: console | ||
$ dffml service http server -insecure -mc-config deploy/webhook -port 8081 | ||
.. note:: | ||
|
||
If you're not setting this up on a server directly accessible on the internet, | ||
here are two methods of exposing the webhook, | ||
|
||
Using `localhost.run <https://localhost.run>`_ | ||
|
||
.. code-block:: console | ||
$ ssh -R 80:localhost:8081 [email protected] | ||
.. image:: ./images/localhost_run.png | ||
|
||
Using ngrok | ||
|
||
.. code-block:: console | ||
$ ~/ngrok http 8081 | ||
.. image:: ./images/ngrok_out.png | ||
|
||
Copy paste the output url to ``Payload URL`` in webhook settings of ffmpeg repo. | ||
|
||
.. image:: ./images/github_settings.png | ||
|
||
Now whenever there's a push to the default branch of the repo, the ffmpeg container | ||
which is running gets redeployed from the fresh pull. To check this we will modify the | ||
end time of the conversion from 10 to 12 in ``ffmpeg/operations.py`` by changing | ||
|
||
.. code-block:: python | ||
proc = await asyncio.create_subprocess_exec( | ||
"ffmpeg", | ||
"-ss", | ||
"0.3", | ||
"-t", | ||
"10", | ||
.. | ||
.. | ||
) | ||
to | ||
|
||
.. code-block:: python | ||
proc = await asyncio.create_subprocess_exec( | ||
"ffmpeg", | ||
"-ss", | ||
"0.3", | ||
"-t", | ||
"12", | ||
.. | ||
.. | ||
) | ||
on pushing the changes to our repo, the container will be redeployed. To verify this run | ||
``docker ps`` and check the up time of the container. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
[run] | ||
source = | ||
ffmpeg | ||
tests | ||
branch = True | ||
|
||
[report] | ||
exclude_lines = | ||
no cov | ||
no qa | ||
noqa | ||
pragma: no cover | ||
if __name__ == .__main__.: |
Oops, something went wrong.