Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganize actions doc. #3816

Merged
merged 7 commits into from Jun 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
157 changes: 157 additions & 0 deletions docs/actions-docker.md
@@ -0,0 +1,157 @@
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
-->

## Creating and invoking Docker actions

With OpenWhisk Docker actions, you can write your actions in any language, bundle larger
or complex dependencies, and tailor the runtime environment to suite your needs.

- As a prerequisite, you must have a Docker Hub account.
To set up a free Docker ID and account, go to [Docker Hub](https://hub.docker.com).
- The easiest way to get started with a Docker action is to use the OpenWhisk Docker skeleton.
- You can install the skeleton with the `wsk sdk install docker` CLI command.
- This is a a Docker image based on [python:3.6.1-alpine](https://hub.docker.com/r/library/python).
- The skeleton requires an entry point located at `/action/exec` inside the container.
This may be an executable script or binary compatible with this distribution.
- The executable receives the input arguments via a single command-line argument string
which can be deserialized as a `JSON` object.
It must return a result via `stdout` as a single-line string of serialized `JSON`.
- You may include any compilation steps or dependencies by modifying the `Dockerfile`
included in the `dockerSkeleton`.

The instructions that follow show you how to use the OpenWhisk Docker skeleton.

1. Install the Docker skeleton.

```
wsk sdk install docker
```
```
The Docker skeleton is now installed at the current directory.
```

```
$ ls dockerSkeleton/
```
```
Dockerfile README.md buildAndPush.sh example.c
```

The skeleton is a Docker container template where you can inject your code in the form of custom binaries.

2. Create the executable. The Docker skeleton includes a C program that you can use as an example.

```
cat dockerSkeleton/example.c
```
```c
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("This is an example log message from an arbitrary C program!\n");
printf("{ \"msg\": \"Hello from arbitrary C program!\", \"args\": %s }",
(argc == 1) ? "undefined" : argv[1]);
}
```

You can modify this file as needed, or, add additional code and dependencies to the Docker image.
In case of the latter, you may need to tweak the `Dockerfile` as necessary to build your executable.
The binary must be located inside the container at `/action/exec`.

The executable receives a single argument from the command line. It is a string serialization of the JSON
object representing the arguments to the action. The program may log to `stdout` or `stderr`.
By convention, the last line of output _must_ be a stringified JSON object which represents the result of
the action.

3. Build the Docker image and upload it using a supplied script.
You must first run `docker login` to authenticate, and then run the script with a chosen image name.

```
docker login -u janesmith -p janes_password
```
```
cd dockerSkeleton
```
```
./buildAndPush.sh janesmith/blackboxdemo
```

Notice that part of the example.c file is compiled as part of the Docker image build process,
so you do not need C compiled on your machine.
In fact, unless you are compiling the binary on a compatible host machine, it may not run inside
the container since formats will not match.

Your Docker container may now be used as an OpenWhisk action.

```
wsk action create example --docker janesmith/blackboxdemo
```

Notice the use of `--docker` when creating an action. Currently all Docker images are assumed
to be hosted on Docker Hub.

## Invoking a Docker action

Docker actions are invoked as [any other OpenWhisk action](actions.md#the-basics).

```
wsk action invoke --result example --param payload Rey
```
```json
{
"args": {
"payload": "Rey"
},
"msg": "Hello from arbitrary C program!"
}
```

## Updating a Docker action

To update the Docker action, run buildAndPush.sh again _and_ update your action.
This will upload the latest image to Docker Hub and force the system to create a new container based on the image.
If you do not update the action, then the image is pulled when there are no warm containers available for your action.
A warm container will continue using a previous version of your Docker image,
and any new invocations of the action will continue to use that image unless you run `wsk action update`.
This will indicate to the system that for new invocations it should execute a docker pull to get your new Docker image.

```
./buildAndPush.sh janesmith/blackboxdemo
```
```
wsk action update example --docker janesmith/blackboxdemo
```

## Creating native actions

Docker actions accept initialization data via a (zip) file, similar to other actions kinds.
For example, the tutorial above created a binary executable inside the container located at `/action/exec`.
If you copy this file to your local file system and zip it into `exec.zip` then you can use the following
commands to create a docker action which receives the executable as initialization data.

```bash
wsk action create example exec.zip --native
```
which is equivalent to the following command.
```bash
wsk action create example exec.zip --docker openwhisk/dockerskeleton
```

Using `--native`, you can see that any executable may be run as an OpenWhisk action.
This includes `bash` scripts, or cross compiled binaries. For the latter, the constraint
is that the binary must be compatible with the `openwhisk/dockerskeleton` image.
83 changes: 83 additions & 0 deletions docs/actions-go.md
@@ -0,0 +1,83 @@
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
-->

## Creating and invoking Go actions

Using OpenWhisk [native actions](actions-docker.md#creating-native-actions),
you can package any executable as an action. This works for Go as an example.
As with [Docker actions](actions-docker.md), the Go executable receives a single argument
from the command line.
It is a string serialization of the JSON object representing the arguments to the action.
The program may log to `stdout` or `stderr`.
By convention, the last line of output _must_ be a stringified JSON object which represents
the result of the action.

Here is an example Go action.
```go
package main

import "encoding/json"
import "fmt"
import "os"

func main() {
//program receives one argument: the JSON object as a string
arg := os.Args[1]

// unmarshal the string to a JSON object
var obj map[string]interface{}
json.Unmarshal([]byte(arg), &obj)

// can optionally log to stdout (or stderr)
fmt.Println("hello Go action")

name, ok := obj["name"].(string)
if !ok { name = "Stranger" }

// last line of stdout is the result JSON object as a string
msg := map[string]string{"msg": ("Hello, " + name + "!")}
res, _ := json.Marshal(msg)
fmt.Println(string(res))
}
```

Save the code above to a file `sample.go` and cross compile it for OpenWhisk.
The executable must be called `exec`.
```bash
GOOS=linux GOARCH=amd64 go build -o exec
zip exec.zip exec
wsk action create helloGo --native exec.zip
```

The action may be run as any other action.
```bash
wsk action invoke helloGo -r -p name gopher
{
"msg": "Hello, gopher!"
}
```

Find out more about parameters in the [Working with parameters](./parameters.md) section.

Logs are retrieved in a similar way as well.

```bash
wsk activation logs --last --strip
my first Go action.
```
93 changes: 93 additions & 0 deletions docs/actions-java.md
@@ -0,0 +1,93 @@
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
-->

## Creating and invoking Java actions

The process of creating Java actions is similar to that of [other actions](actions.md#the-basics).
The following sections guide you through creating and invoking a single Java action,
and demonstrate how to bundle multiple files and third party dependencies.

In order to compile, test and archive Java files, you must have a
[JDK 8](http://www.oracle.com/technetwork/java/javase/downloads/index.html) installed locally.

A Java action is a Java program with a method called `main` that has the exact signature as follows:
```java
public static com.google.gson.JsonObject main(com.google.gson.JsonObject);
```

For example, create a Java file called `Hello.java` with the following content:

```java
import com.google.gson.JsonObject;

public class Hello {
public static JsonObject main(JsonObject args) {
String name = "stranger";
if (args.has("name"))
name = args.getAsJsonPrimitive("name").getAsString();
JsonObject response = new JsonObject();
response.addProperty("greeting", "Hello " + name + "!");
return response;
}
}
```

Then, compile `Hello.java` into a JAR file `hello.jar` as follows:
```
javac Hello.java
```
```
jar cvf hello.jar Hello.class
```

**Note:** [google-gson](https://github.com/google/gson) must exist in your Java CLASSPATH when compiling the Java file.

You can create a OpenWhisk action called `helloJava` from this JAR file as
follows:

```
wsk action create helloJava hello.jar --main Hello
```

When you use the command line and a `.jar` source file, you do not need to
specify that you are creating a Java action;
the tool determines that from the file extension.

You need to specify the name of the main class using `--main`. An eligible main
class is one that implements a static `main` method as described above. If the
class is not in the default package, use the Java fully-qualified class name,
e.g., `--main com.example.MyMain`.

If needed you can also customize the method name of your Java action. This
can be done by specifying the Java fully-qualified method name of your action,
e.q., `--main com.example.MyMain#methodName`

Action invocation is the same for Java actions as it is for Swift and JavaScript actions:

```
wsk action invoke --result helloJava --param name World
```

```json
{
"greeting": "Hello World!"
}
```

Find out more about parameters in the [Working with parameters](./parameters.md) section.