Picasso Demo

Reference (Picasso):

Reference (Iron.io):

Prerequisite:

  • Vagrant
  • devstack

Example configuration of Vagrantfile:

:Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/xenial64"

  # config.vm.box_check_update = false

  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.network "forwarded_port", guest: 8888, host: 18888

  config.vm.network "private_network", ip: "192.168.33.10"

  config.vm.provider "virtualbox" do |vb|
  #   # Display the VirtualBox GUI when booting the machine
  #   vb.gui = true
  #
  #   # Customize the amount of memory on the VM:
    vb.memory = "8192"
  end
end

Install glide, dep, devstack with picasso

Download devstack.

sudo add-apt-repository ppa:masterminds/glide && sudo apt-get update
sudo apt install glide

export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin

# To build 'dep'
# (workaround the toml issue)
sudo tar -C /usr/local -xzf go1.7.linux-amd64.tar.gz
mkdir -p ~/go/bin
go get -u github.com/golang/dep/...

cd $GOPATH/src/github.com/golang/dep
git checkout 8cdbc074c229c0e225a1a37a88fbadef5d988595
go get github.com/golang/dep/...
rm -rf /usr/local/go
unet GOPATH

cd ~
git clone https://git.openstack.org/openstack-dev/devstack.git $DEVSTACK_DIR
cd devstack
cp samples/local.conf ./

As a next step, edit local.conf as follows.

Note: You have to enable aodh and ceilometer to confirm alarm notification.

GIT_BASE=https://git.openstack.org

HOST_IP=192.168.33.10

enable_plugin aodh https://git.openstack.org/openstack/aodh
enable_plugin picasso https://github.com/openstack/picasso.git

CEILOMETER_BACKEND=mongodb
enable_plugin ceilometer https://git.openstack.org/openstack/ceilometer

# Picasso configuration
PICASSO_REPO=${PICASSO_REPO:-https://github.com/openstack/picasso.git}
PICASSO_BRANCH=${PICASSO_BRANCH:-master}
PICASSO_DIR=${PICASSO_DIR:-${DEST}/picasso}
PICASSO_PORT=${PICASSO_PORT:-10001}
PICASSO_LOG_LEVEL=${PICASSO_LOG_LEVEL:-DEBUG}
PICASSO_LOG_FILE=${PICASSO_LOG_FILE:-/var/log/picasso-api.log}

# Picasso client configuration
PICASSO_CLIENT_REPO=${PICASSO_CLIENT_REPO:-https://github.com/openstack/python-picassoclient.git}
PICASSO_CLIENT_DIR=${PICASSO_CLIENT_DIR:-${DEST}/python-picassoclient}
PICASSO_CLIENT_BRANCH=${PICASSO_CLIENT_BRANCH:-master}

# Functions parameters
FUNCTIONS_REPO=${FUNCTIONS_REPO:-https://github.com/iron-io/functions.git}
FUNCTIONS_BRANCH=${FUNCTIONS_BRANCH:-master}
FUNCTIONS_PORT=${FUNCTIONS_PORT:-10501}
FUNCTIONS_DB=${FUNCTIONS_DBPATH:-bolt://$FUNCTIONS_DIR/devstack.functions.storage.db?bucket=funcs}
FUNCTIONS_MQ=${FUNCTIONS_DBPATH:-bolt://$FUNCTIONS_DIR/devstack.functions.queue.db}
FUNCTIONS_LOG_LEVEL=${FUNCTIONS_LOG_LEVEL:-DEBUG}

DOCKER_OPTS=${DOCKER_OPTS:---dns 8.8.8.8 --storage-driver=overlay2 -H fd://}

Then, invoke stack.sh

# For small disk instances:
sudo apt install mongodb-server
sudo vi /etc/mongodb.conf
----
#journal = true
nojournal = true
----
./stack.sh

Issues / Workarounds

aiohttp

vi /opt/stack/picasso/Dockerfile

RUN pip3 install aiohttp==1.3.0

build error of 'functions'

Revert to March/2017 version of 'functions'.

vi /opt/stack/picasso/devstack/plugin.sh

function install_functions {
    echo_summary "Pulling Functions sources"
    git_clone $FUNCTIONS_REPO $GOPATH/src/github.com/iron-io/functions $FUNCTIONS_BRANCH
    (cd $GOPATH/src/github.com/iron-io/functions && git checkout 90f93706f229c90d6465be743e23b40492462831)
    pushd $FUNCTIONS_DIR && GOPATH=${GOPATH} make all; popd
}
In [3]:
source ~/devstack/openrc admin
WARNING: setting legacy OS_TENANT_NAME to support cli tools.
In [4]:
openstack fn apps list

In [5]:
openstack fn apps create alarm-notifier-app
func_name=`openstack fn apps list | grep alarm-notifier-app | awk '{print $2}'`
echo $func_name
+-------------+--------------------------------------------------+
| Field       | Value                                            |
+-------------+--------------------------------------------------+
| name        | alarm-notifier-app-89acd99a48a                   |
| created_at  | 2017-04-19 02:13:11.814701                       |
| updated_at  | 2017-04-19 02:13:11.814715                       |
| project_id  | 89acd99a48a0452b898b3e4f690a5b80                 |
| config      | None                                             |
| id          | 26c3911622a84e729e8df793126443da                 |
| description | App for project 89acd99a48a0452b898b3e4f690a5b80 |
+-------------+--------------------------------------------------+
alarm-notifier-app-89acd99a48a
In [6]:
openstack fn routes create $func_name /hello async iron/hello --is-public
+-----------------+------------+
| Field           | Value      |
+-----------------+------------+
| image           | iron/hello |
| memory          | 128        |
| is_public       | True       |
| timeout         | 30         |
| path            | /hello     |
| max_concurrency | 1          |
| type            | async      |
+-----------------+------------+
In [7]:
nova boot --image $(glance image-list | awk '/cirros-0.3.5-x86_64-disk / {print $2}') --flavor 42 test_alarms
/usr/local/lib/python2.7/dist-packages/novaclient/client.py:278: UserWarning: The 'tenant_id' argument is deprecated in Ocata and its use may result in errors in future releases. As 'project_id' is provided, the 'tenant_id' argument will be ignored.
  warnings.warn(msg)
+--------------------------------------+-----------------------------------------------------------------+
| Property                             | Value                                                           |
+--------------------------------------+-----------------------------------------------------------------+
| OS-DCF:diskConfig                    | MANUAL                                                          |
| OS-EXT-AZ:availability_zone          |                                                                 |
| OS-EXT-SRV-ATTR:host                 | -                                                               |
| OS-EXT-SRV-ATTR:hostname             | test-alarms                                                     |
| OS-EXT-SRV-ATTR:hypervisor_hostname  | -                                                               |
| OS-EXT-SRV-ATTR:instance_name        |                                                                 |
| OS-EXT-SRV-ATTR:kernel_id            |                                                                 |
| OS-EXT-SRV-ATTR:launch_index         | 0                                                               |
| OS-EXT-SRV-ATTR:ramdisk_id           |                                                                 |
| OS-EXT-SRV-ATTR:reservation_id       | r-mx9oafnh                                                      |
| OS-EXT-SRV-ATTR:root_device_name     | -                                                               |
| OS-EXT-SRV-ATTR:user_data            | -                                                               |
| OS-EXT-STS:power_state               | 0                                                               |
| OS-EXT-STS:task_state                | scheduling                                                      |
| OS-EXT-STS:vm_state                  | building                                                        |
| OS-SRV-USG:launched_at               | -                                                               |
| OS-SRV-USG:terminated_at             | -                                                               |
| accessIPv4                           |                                                                 |
| accessIPv6                           |                                                                 |
| adminPass                            | JQUoefbd2g8S                                                    |
| config_drive                         |                                                                 |
| created                              | 2017-04-19T02:13:34Z                                            |
| description                          | -                                                               |
| flavor                               | m1.nano (42)                                                    |
| hostId                               |                                                                 |
| host_status                          |                                                                 |
| id                                   | 49f6c81a-12ad-49bf-9199-6c9ed190cc91                            |
| image                                | cirros-0.3.5-x86_64-disk (3628bb95-0c01-44f7-ba1c-2b13199eeb62) |
| key_name                             | -                                                               |
| locked                               | False                                                           |
| metadata                             | {}                                                              |
| name                                 | test_alarms                                                     |
| os-extended-volumes:volumes_attached | []                                                              |
| progress                             | 0                                                               |
| security_groups                      | default                                                         |
| status                               | BUILD                                                           |
| tags                                 | []                                                              |
| tenant_id                            | 89acd99a48a0452b898b3e4f690a5b80                                |
| updated                              | 2017-04-19T02:13:34Z                                            |
| user_id                              | 6f7eae51aaaa4a868c23e2fb736c87a4                                |
+--------------------------------------+-----------------------------------------------------------------+
In [8]:
aodh alarm create \
    --type threshold \
    --name cpu_high \
    --description 'instance running hot' \
    --meter-name cpu_util \
    --threshold 20.0 \
    --comparison-operator gt \
    --statistic max \
    --period 600 \
    --evaluation-periods 1 \
    --alarm-action $(openstack fn routes expose-url $func_name /hello) \
    --query resource_id=$(nova list | grep test_alarms | awk '{print $2}')
/usr/local/lib/python2.7/dist-packages/novaclient/client.py:278: UserWarning: The 'tenant_id' argument is deprecated in Ocata and its use may result in errors in future releases. As 'project_id' is provided, the 'tenant_id' argument will be ignored.
  warnings.warn(msg)
+---------------------------+--------------------------------------------------+
| Field                     | Value                                            |
+---------------------------+--------------------------------------------------+
| alarm_actions             | [u'http://192.168.33.10:10001/r/alarm-notifier-  |
|                           | app-89acd99a48a/hello']                          |
| alarm_id                  | 268618b5-4b6f-4141-8124-0b4a8c726b6d             |
| comparison_operator       | gt                                               |
| description               | instance running hot                             |
| enabled                   | True                                             |
| evaluation_periods        | 1                                                |
| exclude_outliers          | False                                            |
| insufficient_data_actions | []                                               |
| meter_name                | cpu_util                                         |
| name                      | cpu_high                                         |
| ok_actions                | []                                               |
| period                    | 600                                              |
| project_id                | 89acd99a48a0452b898b3e4f690a5b80                 |
| query                     | resource_id = 49f6c81a-12ad-                     |
|                           | 49bf-9199-6c9ed190cc91                           |
| repeat_actions            | False                                            |
| severity                  | low                                              |
| state                     | insufficient data                                |
| state_timestamp           | 2017-04-19T02:15:12.240495                       |
| statistic                 | max                                              |
| threshold                 | 20.0                                             |
| time_constraints          | []                                               |
| timestamp                 | 2017-04-19T02:15:12.240495                       |
| type                      | threshold                                        |
| user_id                   | 6f7eae51aaaa4a868c23e2fb736c87a4                 |
+---------------------------+--------------------------------------------------+

Place a load on the instance

As a first step, log in to the instance.

Then, invoke dd command so that aodh alarm is going to be fired.

openstack security group rule create default --protocol icmp --remote-ip 0.0.0.0/0
openstack security group rule create default --protocol tcp --dst-port 22:22 --remote-ip 0.0.0.0/0

ns_rq=`ip netns show | grep qrouter`
sudo ip netns exec $ns_rq bash
ssh [email protected]
dd if=/dev/zero of=/dev/null
In [26]:
aodh alarm-history search
+-------------------+-------------------+------------------+-------------------+
| alarm_id          | timestamp         | type             | detail            |
+-------------------+-------------------+------------------+-------------------+
| 268618b5-4b6f-414 | 2017-04-19T02:30: | state transition | {"transition_reas |
| 1-8124-0b4a8c726b | 16.202627         |                  | on": "Transition  |
| 6d                |                   |                  | to alarm due to 1 |
|                   |                   |                  | samples outside   |
|                   |                   |                  | threshold, most   |
|                   |                   |                  | recent:           |
|                   |                   |                  | 38.3480281761",   |
|                   |                   |                  | "state": "alarm"} |
| 268618b5-4b6f-414 | 2017-04-19T02:15: | creation         | {"alarm_actions": |
| 1-8124-0b4a8c726b | 12.240495         |                  | ["http://192.168. |
| 6d                |                   |                  | 33.10:10001/r     |
|                   |                   |                  | /alarm-notifier-  |
|                   |                   |                  | app-89acd99a48a/h |
|                   |                   |                  | ello"],           |
|                   |                   |                  | "user_id": "6f7ea |
|                   |                   |                  | e51aaaa4a868c23e2 |
|                   |                   |                  | fb736c87a4",      |
|                   |                   |                  | "name":           |
|                   |                   |                  | "cpu_high",       |
|                   |                   |                  | "state":          |
|                   |                   |                  | "insufficient     |
|                   |                   |                  | data",            |
|                   |                   |                  | "timestamp": "201 |
|                   |                   |                  | 7-04-19T02:15:12. |
|                   |                   |                  | 240495",          |
|                   |                   |                  | "description":    |
|                   |                   |                  | "instance running |
|                   |                   |                  | hot", "enabled":  |
|                   |                   |                  | true, "state_time |
|                   |                   |                  | stamp": "2017-04- |
|                   |                   |                  | 19T02:15:12.24049 |
|                   |                   |                  | 5", "rule":       |
|                   |                   |                  | {"meter_name":    |
|                   |                   |                  | "cpu_util", "eval |
|                   |                   |                  | uation_periods":  |
|                   |                   |                  | 1, "period": 600, |
|                   |                   |                  | "statistic":      |
|                   |                   |                  | "max",            |
|                   |                   |                  | "threshold":      |
|                   |                   |                  | 20.0, "query":    |
|                   |                   |                  | [{"field":        |
|                   |                   |                  | "resource_id",    |
|                   |                   |                  | "type": "",       |
|                   |                   |                  | "value":          |
|                   |                   |                  | "49f6c81a-12ad-49 |
|                   |                   |                  | bf-9199-6c9ed190c |
|                   |                   |                  | c91", "op":       |
|                   |                   |                  | "eq"}], "comparis |
|                   |                   |                  | on_operator":     |
|                   |                   |                  | "gt", "exclude_ou |
|                   |                   |                  | tliers": false},  |
|                   |                   |                  | "alarm_id": "2686 |
|                   |                   |                  | 18b5-4b6f-4141-81 |
|                   |                   |                  | 24-0b4a8c726b6d", |
|                   |                   |                  | "time_constraints |
|                   |                   |                  | ": [], "insuffici |
|                   |                   |                  | ent_data_actions" |
|                   |                   |                  | : [],             |
|                   |                   |                  | "repeat_actions": |
|                   |                   |                  | false,            |
|                   |                   |                  | "ok_actions": [], |
|                   |                   |                  | "project_id": "89 |
|                   |                   |                  | acd99a48a0452b898 |
|                   |                   |                  | b3e4f690a5b80",   |
|                   |                   |                  | "type":           |
|                   |                   |                  | "threshold",      |
|                   |                   |                  | "severity":       |
|                   |                   |                  | "low"}            |
+-------------------+-------------------+------------------+-------------------+

How to check log of execution

It seems that Iron.io does not support convenient way to check execution history so far. You can track history on syslog.

In [29]:
grep "Apr 19 02:30" /var/log/syslog  | grep functions
Apr 19 02:30:16 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:16Z" level=debug msg="Finding route on datastore" action="server.handleRunnerRequest)-fm" app=alarm-notifier-app-89acd99a48a call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5 path="/hello" route="/hello"
Apr 19 02:30:16 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:16Z" level=debug msg="Got routes from datastore" action="server.handleRunnerRequest)-fm" app=alarm-notifier-app-89acd99a48a call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5 route="/hello" routes=1
Apr 19 02:30:16 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:16Z" level=info msg="Pushed to MQ" call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5
Apr 19 02:30:16 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:16Z" level=info msg="Added new task to queue" action="server.handleRunnerRequest)-fm" app=alarm-notifier-app-89acd99a48a call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5 image="iron/hello" route="/hello"
Apr 19 02:30:16 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:16Z" level=info msg=Reserved call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5
Apr 19 02:30:16 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:16Z" level=debug msg="Running task:07713835-50e5-5c9a-bd7f-ee661d0fd5c5" call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5 runner=async
Apr 19 02:30:16 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:16Z" level=debug msg="Processed task" call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5 runner=async
Apr 19 02:30:16 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:16Z" level=info call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5 name=run.alarm-notifier-app-89acd99a48a.requests runner=async type=count value=1
Apr 19 02:30:16 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:16Z" level=info call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5 name=run.alarm-notifier-app-89acd99a48a.waittime runner=async type=time value=0s
Apr 19 02:30:16 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:16Z" level=info msg=Deleted call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5
Apr 19 02:30:16 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:16Z" level=info msg="Task complete" call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5 runner=async
Apr 19 02:30:17 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:17Z" level=debug msg="Starting container execution" call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5 container=task-1492569016991038844-07713835-50e5-5c9a-bd7f-ee661d0fd5c5 runner=async
Apr 19 02:30:17 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:17Z" level=info msg="Hello World!" app_name=alarm-notifier-app-89acd99a48a call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5 image="iron/hello" path= runner=async user_log=true
Apr 19 02:30:17 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:17Z" level=info msg="container status" call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5 container_error= container_finished=2017-04-19 02:30:17.340404294 +0000 UTC container_running=false container_status=exited exit_code=0 runner=async
Apr 19 02:30:17 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:17Z" level=info call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5 name=run.alarm-notifier-app-89acd99a48a.succeeded runner=async type=count value=1
Apr 19 02:30:17 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:17Z" level=info call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5 name=run.alarm-notifier-app-89acd99a48a.time runner=async type=time value=440.736062ms
Apr 19 02:30:17 ubuntu-xenial functions[23573]: time="2017-04-19T02:30:17Z" level=info call_id=07713835-50e5-5c9a-bd7f-ee661d0fd5c5 name="run.exec_time" runner=async type=time value=440.736062ms

How to display apps / routes by using openstack CLI

In [12]:
openstack fn routes list $func_name
+-------+--------+----------+--------+---------+-----------------+-----------+--------+
| type  | path   | image    | memory | timeout | max_concurrency | is_public | config |
+-------+--------+----------+--------+---------+-----------------+-----------+--------+
| async | /hello | iron/hel |    128 |      30 |               1 | True      |        |
|       |        | lo       |        |         |                 |           |        |
+-------+--------+----------+--------+---------+-----------------+-----------+--------+
In [13]:
openstack fn routes show $func_name /hello
+-----------------+------------+
| Field           | Value      |
+-----------------+------------+
| image           | iron/hello |
| memory          | 128        |
| is_public       | True       |
| timeout         | 30         |
| path            | /hello     |
| max_concurrency | 1          |
| type            | async      |
+-----------------+------------+

How to display apps / routes by using iron.io CLI

Operators can also be accessd to iron.io via native API or fn-CLI directly.

To install 'fn' command, invoke following url.

curl -LSs https://goo.gl/VZrL8t | sh
In [16]:
export API_URL=http://localhost:10501
In [17]:
fn apps list
alarm-notifier-app-89acd99a48a
In [18]:
fn routes list $func_name
path	image	endpoint
/hello	iron/hello
In [30]:
fn routes call $func_name /hello
{"call_id":"71c8630b-f2fb-5bce-b022-62e635247df8"}
In [32]:
grep 71c8630b-f2fb-5bce-b022-62e635247df8 /var/log/syslog
Apr 19 02:35:07 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:07Z" level=debug msg="Finding route on datastore" action="server.handleRunnerRequest)-fm" app=alarm-notifier-app-89acd99a48a call_id=71c8630b-f2fb-5bce-b022-62e635247df8 path="/hello" route="/hello"
Apr 19 02:35:07 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:07Z" level=debug msg="Got routes from datastore" action="server.handleRunnerRequest)-fm" app=alarm-notifier-app-89acd99a48a call_id=71c8630b-f2fb-5bce-b022-62e635247df8 route="/hello" routes=1
Apr 19 02:35:07 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:07Z" level=info msg="Pushed to MQ" call_id=71c8630b-f2fb-5bce-b022-62e635247df8
Apr 19 02:35:07 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:07Z" level=info msg="Added new task to queue" action="server.handleRunnerRequest)-fm" app=alarm-notifier-app-89acd99a48a call_id=71c8630b-f2fb-5bce-b022-62e635247df8 image="iron/hello" route="/hello"
Apr 19 02:35:08 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:08Z" level=info msg=Reserved call_id=71c8630b-f2fb-5bce-b022-62e635247df8
Apr 19 02:35:08 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:08Z" level=debug msg="Running task:71c8630b-f2fb-5bce-b022-62e635247df8" call_id=71c8630b-f2fb-5bce-b022-62e635247df8 runner=async
Apr 19 02:35:08 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:08Z" level=debug msg="Processed task" call_id=71c8630b-f2fb-5bce-b022-62e635247df8 runner=async
Apr 19 02:35:08 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:08Z" level=info call_id=71c8630b-f2fb-5bce-b022-62e635247df8 name=run.alarm-notifier-app-89acd99a48a.requests runner=async type=count value=1
Apr 19 02:35:08 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:08Z" level=info call_id=71c8630b-f2fb-5bce-b022-62e635247df8 name=run.alarm-notifier-app-89acd99a48a.waittime runner=async type=time value=0s
Apr 19 02:35:08 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:08Z" level=info msg=Deleted call_id=71c8630b-f2fb-5bce-b022-62e635247df8
Apr 19 02:35:08 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:08Z" level=info msg="Task complete" call_id=71c8630b-f2fb-5bce-b022-62e635247df8 runner=async
Apr 19 02:35:08 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:08Z" level=debug msg="Starting container execution" call_id=71c8630b-f2fb-5bce-b022-62e635247df8 container=task-1492569308306242597-71c8630b-f2fb-5bce-b022-62e635247df8 runner=async
Apr 19 02:35:08 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:08Z" level=info msg="Hello World!" app_name=alarm-notifier-app-89acd99a48a call_id=71c8630b-f2fb-5bce-b022-62e635247df8 image="iron/hello" path= runner=async user_log=true
Apr 19 02:35:08 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:08Z" level=info msg="container status" call_id=71c8630b-f2fb-5bce-b022-62e635247df8 container_error= container_finished=2017-04-19 02:35:08.556707421 +0000 UTC container_running=false container_status=exited exit_code=0 runner=async
Apr 19 02:35:08 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:08Z" level=info call_id=71c8630b-f2fb-5bce-b022-62e635247df8 name=run.alarm-notifier-app-89acd99a48a.succeeded runner=async type=count value=1
Apr 19 02:35:08 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:08Z" level=info call_id=71c8630b-f2fb-5bce-b022-62e635247df8 name=run.alarm-notifier-app-89acd99a48a.time runner=async type=time value=334.906475ms
Apr 19 02:35:08 ubuntu-xenial functions[23573]: time="2017-04-19T02:35:08Z" level=info call_id=71c8630b-f2fb-5bce-b022-62e635247df8 name="run.exec_time" runner=async type=time value=334.906475ms

How to create functions

export DOCKER_HOST=tcp://localhost:2375

mkdir ~/picasso-func ; cd ~/picasso-func
vi func.go

func.go:

package main

import (
    "encoding/json"
    "fmt"
    "os"
)

type Person struct {
    Name string
}

func main() {
    p := &Person{Name: "World"}
    json.NewDecoder(os.Stdin).Decode(p)
    fmt.Printf("Hello %v!", p.Name)
}
fn init testuser/hello
fn build
fn run
fn build && fn push
fn apps create myapp
fn routes create myapp /hello
In [18]:
export DOCKER_HOST=tcp://localhost:2375
docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
testuser/hello      0.0.1               d2a63df5a52d        5 minutes ago       12.6 MB
picasso-api         latest              f8aa15239468        2 hours ago         791 MB
<none>              <none>              60be38a5d6e7        20 hours ago        791 MB
<none>              <none>              dbf4f0595bb5        24 hours ago        791 MB
<none>              <none>              42a97c056272        26 hours ago        791 MB
<none>              <none>              d719aa45609a        26 hours ago        791 MB
python              3.5                 4e5ed9f6613e        8 days ago          687 MB
iron/go             dev                 3d25645a73f8        2 weeks ago         857 MB
iron/hello          latest              f4dd2a73dac8        4 months ago        12.1 MB
iron/go             latest              c05f82fa066a        12 months ago       10.5 MB
In [19]:
curl $API_URL/r/myapp/hello
Hello World!
In [20]:
fn apps list
alarm-notifier-app-5811d3471a5
alarm-notifier-app-db507b128d5
myapp
In [21]:
fn routes  list myapp
path	image	endpoint
/hello	testuser/hello:0.0.1