Merge "Add an example for function cookbook"

This commit is contained in:
Zuul 2018-07-05 06:18:07 +00:00 committed by Gerrit Code Review
commit 8572e2b01f
2 changed files with 270 additions and 1 deletions

View File

@ -14,4 +14,3 @@
Python developer guide Python developer guide
====================== ======================

View File

@ -18,8 +18,278 @@ Function Cookbook
Introduction Introduction
~~~~~~~~~~~~ ~~~~~~~~~~~~
Qinling function lets you execute your code in a serverless environment without
having to first create a VM or container. This cookbook contains several
examples for how to create functions in Qinling.
Examples Examples
~~~~~~~~ ~~~~~~~~
Create python function with libraries in a package Create python function with libraries in a package
-------------------------------------------------- --------------------------------------------------
This guide describes how to create a python function with libraries in a
package and how to invoke the function in a Python runtime(the steps assume
there is already a Python 2.7 runtime available in the deployment).
The function resizes an image which stores in Swift and uploads the resized
image to a new container with a same object name. For the function to work, a
python library called ``Pillow`` needs to be installed together with the
function code, the ``python-swiftclient`` doesn't need to be installed because
Qinling supports it as a built-in library in Qinling's default Python 2.7
runtime implementation.
The function needs two positional parameters:
* ``container_name``: The container name in Swift that the original image file
is stored in.
* ``object_name``: The object name in the container.
There is no output for the function itself, but you can check the function
execution log to see the whole process.
.. note::
The following process has been tested in a Devstack environment in which
Swift is also installed.
#. Create a directory, for example ``~/qinling_test``
.. code-block:: console
$ mkdir ~/qinling_test
.. end
#. Write a custom python code for resizing an image at the root level of the
directory created above.
.. code-block:: console
$ cat <<EOF > ~/qinling_test/resize_image.py
import os
from PIL import Image
import swiftclient
from swiftclient.exceptions import ClientException
def resize_image(image_path, resized_path):
with Image.open(image_path) as image:
image.thumbnail(tuple(x / 4 for x in image.size))
image.save(resized_path)
def main(context, container_name, object_name):
conn = swiftclient.Connection(
session=context['os_session'],
os_options={'region_name': 'RegionOne'},
)
# Download original image
image_path = os.path.abspath('./%s' % object_name)
_, obj_contents = conn.get_object(container_name, object_name)
with open(image_path, 'w') as local:
local.write(obj_contents)
print('Downloaded object %s from container %s' % (object_name, container_name))
thumb_path = os.path.abspath('./%s_resized.png' % object_name)
resize_image(image_path, thumb_path)
print('Resized.')
# Create new container if needed
new_container_name = '%s_resized' % container_name
try:
conn.head_container(new_container_name)
except ClientException:
conn.put_container(new_container_name)
print("New container %s created." % new_container_name)
# Upload resized image
with open(thumb_path, 'r') as new_local:
conn.put_object(
new_container_name,
object_name,
contents=new_local,
content_type='text/plain'
)
os.remove(image_path)
os.remove(thumb_path)
print('Uploaded object %s to container %s' % (object_name, new_container_name))
EOF
.. end
#. Install the python libraries necessary for the program execution using
``pip``. The libraries need to be installed at the root level of the
directory.
.. code-block:: console
pip install module-name -t path/to/dir
.. end
In this example, we would install the library ``Pillow`` in the project
directory.
.. code-block:: console
$ pip install Pillow -t ~/qinling_test
.. end
.. note::
Qinling's default Python runtime includes most of the OpenStack project
SDKs, so you don't need to include python-swiftclient in your function
code package, but you can optionally include it for your local testing.
#. Add the contents of the whole directory to a zip file which is now your
function code package. Make sure you zip the contents of the directory and
not the directory itself.
.. code-block:: console
$ cd ~/qinling_test; zip -r9 ~/qinling_test/resize_image.zip .
.. end
#. Create function and get the function ID, replace the ``runtime_id`` with
the one in your deployment.
.. code-block:: console
$ runtime_id=601efeb8-3e41-4e5c-a12a-986dbda252e3
$ openstack function create --name resize_image \
--runtime $runtime_id \
--entry resize_image.main \
--package ~/qinling_test/resize_image.zip
+-------------+-------------------------------------------------------------------------+
| Field | Value |
+-------------+-------------------------------------------------------------------------+
| id | f8b18de6-1751-46d6-8c0d-0f1ecf943d12 |
| name | resize_test |
| description | None |
| count | 0 |
| code | {u'source': u'package', u'md5sum': u'ae7ad9ae450a8c5c31dca8e96f42247c'} |
| runtime_id | 685c1e6c-e175-4b32-9ec4-244d39c1077e |
| entry | resize_image.main |
| project_id | a1e58c83923a4e2ca9370df6007c7fe6 |
| created_at | 2018-07-03 04:38:50.147277 |
| updated_at | None |
| cpu | 100 |
| memory_size | 33554432 |
+-------------+-------------------------------------------------------------------------+
$ function_id=f8b18de6-1751-46d6-8c0d-0f1ecf943d12
.. end
#. Upload an image to Swift.
.. code-block:: console
$ curl -SL http://greenstack.die.upm.es/files/2017/10/sydney-openstack-summit-750x422.jpg -o ~/origin.jpg
$ openstack container create origin_folder
+---------------------------------------+---------------+------------------------------------+
| account | container | x-trans-id |
+---------------------------------------+---------------+------------------------------------+
| AUTH_a1e58c83923a4e2ca9370df6007c7fe6 | origin_folder | tx664a23a4a6e345b6af30d-005b3b6127 |
+---------------------------------------+---------------+------------------------------------+
$ openstack object create origin_folder ~/origin.jpg --name image
+--------+---------------+----------------------------------+
| object | container | etag |
+--------+---------------+----------------------------------+
| image | origin_folder | 07855978284adfcbbf76954a7c654a74 |
+--------+---------------+----------------------------------+
$ openstack object show origin_folder image
+----------------+---------------------------------------+
| Field | Value |
+----------------+---------------------------------------+
| account | AUTH_a1e58c83923a4e2ca9370df6007c7fe6 |
| container | origin_folder |
| content-length | 45957 |
| content-type | application/octet-stream |
| etag | 07855978284adfcbbf76954a7c654a74 |
| last-modified | Tue, 03 Jul 2018 11:44:33 GMT |
| object | image |
+----------------+---------------------------------------+
.. end
#. Invoke the function by specifying function_id and the function inputs as
well.
.. code-block:: console
$ openstack function execution create $function_id --input '{"container_name": "origin_folder", "object_name": "image"}'
+------------------+-------------------------------------------------------------+
| Field | Value |
+------------------+-------------------------------------------------------------+
| id | 04c60ae7-08c9-454c-9b2c-0bbf36391159 |
| function_id | d3de49fc-7488-4635-aa48-84e754881eb8 |
| function_version | 0 |
| description | None |
| input | {"object_name": "image", "container_name": "origin_folder"} |
| result | {"duration": 2.74, "output": null} |
| status | success |
| sync | True |
| project_id | a1e58c83923a4e2ca9370df6007c7fe6 |
| created_at | 2018-07-03 09:12:12 |
| updated_at | 2018-07-03 09:12:16 |
+------------------+-------------------------------------------------------------+
.. end
#. Check the function execution log.
.. code-block:: console
$ openstack function execution log show 04c60ae7-08c9-454c-9b2c-0bbf36391159
Start execution: 04c60ae7-08c9-454c-9b2c-0bbf36391159
Downloaded object image from container origin_folder
Resized.
New container origin_folder_resized created.
Uploaded object image to container origin_folder_resized
Finished execution: 04c60ae7-08c9-454c-9b2c-0bbf36391159
.. end
#. Verify that a new object of smaller size was created in a new container in
Swift.
.. code-block:: console
$ openstack container list
+-----------------------+
| Name |
+-----------------------+
| origin_folder |
| origin_folder_resized |
+-----------------------+
$ openstack object list origin_folder_resized
+-------+
| Name |
+-------+
| image |
+-------+
$ openstack object show origin_folder_resized image
+----------------+---------------------------------------+
| Field | Value |
+----------------+---------------------------------------+
| account | AUTH_a1e58c83923a4e2ca9370df6007c7fe6 |
| container | origin_folder_resized |
| content-length | 31779 |
| content-type | text/plain |
| etag | f737cc7f0fe5c15d8a6897c8fe159c02 |
| last-modified | Tue, 03 Jul 2018 11:46:40 GMT |
| object | image |
+----------------+---------------------------------------+
.. end
Pay attention to the object ``content-length`` value which is smaller than
the original object.