There are two images provided: the
actionloop and the
action-golang-v1.11 available. Each image accept different input in the deployment.
If the input is a single file, it can be either a in ELF format for architecture AMD64 implementing the ActionLoop protocol.
It can also be a script, identified by the
#! hash-bang path at the beginning. The default
actionloop can execute
bash shell scripts and can use the
jq command to parse JSON files and the
curl command to invoke other actions.
If the file is a zipped file, it must contain in the top level (not in a subdirectory) an file named
exec. This file must be in the same format as a single binary, either a binary or a script.
execin the top level, and it must be again a Linux ELF executable compiled for the AMD64 architecture
execwill be interpreted as a collection of zip files, and it will be compiled in a binary as described in the document about actions
Please note in the separate the rules about the name of the main function (that defaults to
main.Main), and the rules about how to overwrite the
When you deploy a zip file, you can:
If all your functions are in the main package, just place all your sources in the top level of your zip file
If some functions belong to a package, like
hello/, you need to be careful with the layout of your source. The layout supported is the following:
golang-main-package/ ├── Makefile └── src ├── hello │ ├── hello.go │ └── hello_test.go └── main.go
You need to use a
src folder, place the sources that belongs to the main package in the
src and place sources of your package in the
Then you should import it your subpackage with
import "hello". Note that this means if you want to compile locally you have to set your GOPATH to parent directory of your
src packages. Check below for using VcCode as an editor with this setup.
When you send the image you will have to zip the content
Check the example
golang-main-package and the associated
Makefile for an example including also how to deploy and precompile your sources.
When you need to use third part libraries, the runtime does not download them from Internet. You have to provide them, downloading and placing them using the
vendor folder mechanism. We are going to show here how to use the vendor folder with the
vendor folder does not work at the top level, you have to use a
src folder and a package folder to have also the vendor folder.
If you want for example use the library
github.com/sirupsen/logrus to manage your logs (a widely used drop-in replacement for the standard
log package), you have to include it in your source code in a sub package.
For example consider you have in the file
src/hello/hello.go the import:
To create a vendor folder, you need to
src/hellofolder (not the
GOPATH=$PWD/../.. dep initthe first time (it will create 2 manifest files
dep ensureif you already have the manifest files.
The layout will be something like this:
golang-hello-vendor ├── Makefile └── src ├── hello │ ├── Gopkg.lock │ ├── Gopkg.toml │ ├── hello.go │ ├── hello_test.go │ └── vendor │ ├── github.com/... │ └── golang.org/... └── hello.go
Check the example
Note you do not need to store the
vendor folder in the version control system as it can be regenerated (only the manifest files), but you need to include the entire vendor folder when you deploy the action.
If you need to use vendor folder in the main package, you need to create a directory
main and place all the source code that would normally go in the top level, in the
main folder instead. A vendor folder in the top level does not work.
If you are using VsCode as your Go development environment with the VsCode Go support, and you want to get rid of errors and have it working properly, you need to configure it to support the suggested:
srcfolder in your source
srcfolder as the top level source or add it as a folder in the workspace (not just have it as a subfolder)
Using this option, the GOPATH will be set to the parent directory of your
src folder and you will not have errors in your imports.
Compiling sources on the image can take some time when the images is initialized. You can speed up precompiling the sources using the image
action-golang-v1.11 as an offline compiler. You need
docker for doing that.
The images accepts a
-compile <main> flag, and expects you provide sources in standard input. It will then compile them, emit the binary in standard output and errors in stderr. The output is always a zip file containing an executable.
If you have docker, you can do it this way:
If you have a single source maybe in file
main.go, with a function named
Main just do this:
docker run openwhisk/action-golang-v1.11 -compile main <main.go >main.zip
If you have multiple sources in current directory, even with a subfolder with sources, you can compile it all with:
zip -r - * | docker run openwhisk/action-golang-v1.11 -compile main >main.zip
The generated executable is suitable to be deployed in OpenWhisk using just the generic
wsk action create my/action main.zip -docker openwhisk/actionloop
You can also use the full
action-golang-v1.11 as runtime, it is only bigger.
Note that the output is always a zip file in Linux AMD64 format so the executable can be run only inside a Docker Linux container.