Making Custom Functions
If a custom function is required in case there are no Direktiv functions available it is easy to create those. Direktiv is pulling the images defined in the functions
section and executes the container in the flow. They can be in any repository.
functions:
- id: custom
image: mycompany/customfunction
type: knative-workflow
The custom container just need to implement a few things. The most important requirement is to listen to port 8080
. The data in the flow will be posted to the container on that port.
- id: notify
type: action
action:
function: custom
input:
hello: world
In the above example Direktiv would post JSON { "hello": "world" }
to the function. The function can use his date to execute whatever it needs to do. After that the function has to return in JSON formart. Direktiv will fetch the response and add it to the state data in the return
attribute. The flow can use that data and proceed.
Reporting Errors
If something goes wrong a function can report an error to the calling flow instance by adding HTTP headers to the response. If these headers are populated the execution of the function will be considered a failure regardless of what's stored in response data.
The headers to report errors are: Direktiv-ErrorCode
and Direktiv-ErrorMessage
. If an error message is defined without defining an error code the calling flow instance will be marked as "crashed" without exposing any helpful information, so it's important to always define both. Errors raised by functions are always 'catchable' by their error codes.
"Direktiv-ErrorCode": "myapp.input",
"Direktiv-ErrorMessage": "Missing 'customerId' property in JSON input."
Logging
Logging for functions is a simple HTTP POST or GET request to the address:
http://localhost:8889/log?aid=$ACTIONID
If POST is used the body of the request is getting logged for GET requests add a log request parameter. The important parameter is $ACTIONID. Each requests gets an action id header which identifies the flow instance. This parameter has to be passed back to attach the log to the instance. This information is passed in as in the initial request (Direktiv-ActionID).
Examples
Using Generic Containers
Direktiv has a special command to use any conatiner from a container registry even if it does not have a server running on port 8080
. If the the command /usr/share/direktiv/direktiv-cmd
in the cmd
field is used Direktiv provides a server for this function / container.
This can be useful if e.g. a Python container is used for scripting or bash
for ssh/scp comands.
direktiv_api: workflow/v1
functions:
- id: get
image: alpine
type: knative-workflow
cmd: /usr/share/direktiv/direktiv-cmd
states:
- id: getter
type: action
action:
function: get
input:
data:
commands:
- command: echo -n "hello"
envs:
- name: MYENV
value: MYVALUE
stop: true
The commands
block holds an array of individual commands which will be excuted in the function. The commands can have three additional parameters.
stop
: If the execution should stop if an error occurs during this command (default: false).suppress_command
: If the command should be printed when executed. Should be set to true if passwords are part of the command (default: false).suppress_output
: If the stdout output of the command should be printed (default: false).env
: A list ov environment variables withname
/value
pairs for this single command.
The is an additional files block which allows to pass in files on-demand. A file requires a name
and content
. The content can be text-based data including
Direktiv secrets. An additional setting is permission
. If the file is an executable script or certificate the permissions can be set via that option.
direktiv_api: workflow/v1
functions:
- id: get
image: alpine
type: knative-workflow
cmd: /usr/share/direktiv/direktiv-cmd
states:
- id: getter
type: action
action:
function: get
input:
files:
- name: script.sh
content: |
#!/bin/sh
echo -n "HELLO WORLD"
permission: 0755
data:
commands:
- command: ./script.sh