apache / openwhisk

Apache OpenWhisk is an open source serverless cloud platform
https://openwhisk.apache.org/
Apache License 2.0
6.54k stars 1.17k forks source link

bash kind action #2927

Closed style95 closed 4 years ago

style95 commented 7 years ago

Shell script is commonly used. If we can create an action with shell script, many users can take advantage of OpenWhisk. Even they can automate their bash logics or provide it as a REST API.

For example, if someone wants to use OpenStack client feature in OpenWhisk action, it is also possible to implement all logics with OpenStack sdk. But it is too time-wasting job to implement all the features because there are huge number of features.

Instead, user can define shell script which execute openstack cli and delegate to it. User can easily use all functionalities of OpenStack client and automate painful shell-accessing jobs.

It is just an example, I think there might be more use-cases for bash kind action.

In this scene, it would be important to define pre-installed packages.

rabbah commented 6 years ago

@style95 this is already supported - the default docker skeleton in fact executes a bash script. Also this article shows how to use the bash support to support a Go action: https://www.ibm.com/blogs/bluemix/2017/01/docker-bluemix-openwhisk/

So you could alias the skeleton as a bash kind in the manifest - I think this would be sufficient to support --kind bash.

sungjunyoung commented 6 years ago

@style95 The bash script has an problem for reading openwhisk’s JSON parameters and responsing JSON.

I have modified the code on dockerskeleton’s actionproxy.py slightly, It allows you to access the value of json from the bash by supplying the json key as an environment variable.

Visit my repository :)

If you want to execute cli command that not in docker image, you just write install script in bash script (exec) when the script is called for the first time

It will be nice to support --kind bash for bash script @rabbah

style95 commented 6 years ago

@rabbah great documents! I knew we can run any bash script or binaries with custom docker skeleton but I couldn't imagine such use cases. That would be very useful when user want to add their own dependencies without pulling custom docker image.

For clarity, I wanted --kind bash in this pr. User will be able to create an action like this:

wsk action create hello hello.sh

Then users can also more easily take advantage of what you mentioned to add dependencies.

@sungjunyoung It seems your changes will be valuable when user uses bash action. How about creating a PR with your changes. We can get more people involved and discuss your approach in depth. It would be more easier to get your changes as well ;)

sungjunyoung commented 6 years ago

I'm currently working to do that people can create custom action with bash script. I'll create PR In the near future. Thanks, @style95 !

rabbah commented 6 years ago

@sungjunyoung thanks for sharing your changes - looks like the main change you made is to recursively project the JSON object's fields into env vars. Did you consider using jq instead?

> cat exec 
#!/bin/bash

apk update && apk add jq 

ARGS=$@
A=`echo "$ARGS" | jq '."a"'`
B=`echo "$ARGS" | jq '."b"'`
C=`echo "$ARGS" | jq '."c"[0]'`
RES=$(($B + $C))

echo A is $A
echo "{\"result\": $RES }"
> wsk action create bash exec --native
ok: created action bash

> wsk action invoke bash -p a A -p b 123 -p c '[1,2,3]' -r
{
    "result": 124
}

jq isn't installed in the base docker skeleton image yet but that'll be useful to add. It would avoid modifying the proxy as an alternative.

(The other change I see in the proxy is the auto boxing of the last line into a JSON object for convenience.)

sungjunyoung commented 6 years ago

@rabbah jq seems to be a better alternative in that users can write code without changing the proxy. Still, if openwhisk support kind --bash, user can use it more familiar. Furthermore, it would be even more surprising if the user could customize the runtime (ex, wsk runtime resister --name bash --docker <my-docker>) and register it locally.

rabbah commented 6 years ago

The easiest way to support kind --bash if that's what you'd like to achieve is to adjust the runtime manifest to add a new kind

diff --git a/ansible/group_vars/all b/ansible/group_vars/all
index 02c2b08..8b0deb1 100644
--- a/ansible/group_vars/all
+++ b/ansible/group_vars/all
@@ -96,6 +96,12 @@ runtimesManifestDefault:
       deprecated: false
       image:
         name: "action-php-v7.1"
+    bash:
+    - kind: "bash"
+      default: true
+      deprecated: false
+      image:
+        name: "dockerskeleton"

Note that I'm reusing the dockerskeleton image. Then you can do this (after redeploying controller & invoker):

> wsk action create mybash exec --kind bash
ok: created action mybash

> wsk action invoke mybash -p b 123 -p c '[1,2,3]' -r
{
    "result": 124
}

+1 to the idea of allowing users to register their docker images as kinds. I see this related to re-architecting how we handle docker actions in general (related to: https://github.com/apache/incubator-openwhisk/issues/1362#issuecomment-337943114)

junoyoon commented 6 years ago

@rabbah

We firstly used jq but dropped it after a while. It's because parsing parameter with jq seems to be hard to use and not intuitive. If we let users to use jq to acquire the parameter, they might choose python or nodejs rather than bash kind. We think env var is well integrated to bash and users might take this approach very easily and facilitate the use of bash kind. Any opinion for this?

sungjunyoung commented 6 years ago

@rabbah Can I get some information about discussion of this issue? The use of jq and the use of recursively registered env vars each seem to have pros and cons.

  1. use of jq

    • pros
      • Users who are familiar with jq are easy to use.
      • Not need to touch the dockerskeleton unless to install jq on the docker.
    • cons
      • Users who are unfamiliar with jq are hard to use
      • jq can parse deep depth JSON, But users who want to use the bash action do not usually request complex parameters.
  2. use of recursively registered env vars with auto boxing

    • pros
      • Users do not have to think about JSON parsing in the bash script.
      • If users want to return simple string (ok / fail), Also Users do not have to think about JSON formatting to response
      • Not need to install jq in docker
    • cons

If dockerfile that I modified pushed to openwhisk dockerhub repository, I think I can test and send PR for more discussion. What do you think about this?

rabbah commented 6 years ago

The convenience of the runtime manifest is that for private deployments you deploy which images you want or need including replacing the openwhisk ones on dockerhub with organization specific ones. So one approach is to leave the. openwhisk docker skeleton alone and either publish your own or simply integrate it with your build and deployment.

The down side of modifying the skeleton that’s part of the current base image is that you’ll incur the cost of recursively walking a json object whether the action is a bash one or not. I don’t know what the performance impact of that might be but for the majority of docker actions I suspect this will be unnecessary overhead.

If as you say users for bash scripts will not expect complex objects than a simple jq query is straight forward.

You’re welcome to open a pull request and also raise discussion on the dev list.

rabbah commented 6 years ago

Another alternative is to create a new kind and override the behavior of the default proxy (see the swift action for an example).

sungjunyoung commented 6 years ago

@rabbah Thanks for a quick answer and I undertood about issue that could be happen. Seems to be good alternative that override the behavior of default proxy. :) I'll take a look at it.

upgle commented 6 years ago

I opened PR it on behalf of @sungjunyoung. #3138 cc. @rabbah