Docs update with new fnctl commands (#273)

* Added high level roadmap.

* Changed to funtion.yaml.

* Added logo

* updating quickstart code example, WIP, waiting on another merge.

* Minor updates.

* Changed function.yaml to func.yaml and updated fnctl README.
This commit is contained in:
Travis Reeder
2016-11-14 16:40:05 -08:00
committed by C Cirello
parent 2d3601c588
commit 0d71e1e38e
27 changed files with 284 additions and 182 deletions

View File

@@ -1,7 +1,7 @@
FROM iron/dind
RUN mkdir /app
ADD functions-alpine /app/functions
WORKDIR /app
ADD functions-alpine /app/functions
CMD ["./functions"]

View File

@@ -1,4 +1,4 @@
# IronFunctions
![IronFunctions](docs/assets/logo-black-400w.png)
[![CircleCI](https://circleci.com/gh/iron-io/functions.svg?style=svg)](https://circleci.com/gh/iron-io/functions)
[![GoDoc](https://godoc.org/github.com/iron-io/functions?status.svg)](https://godoc.org/github.com/iron-io/functions)
@@ -8,7 +8,7 @@ Welcome to IronFunctions! The open source serverless platform.
## What is IronFunctions?
IronFunctions is an open source serverless platform, or as we like to refer to it, Functions as a
Service (FaaS) platform that you can run anywhere.
Service (FaaS) platform that you can run anywhere.
* [Run anywhere](docs/faq.md#where-can-i-run-ironfunctions)
* Public cloud, hybrid, on-premise
@@ -17,6 +17,8 @@ Service (FaaS) platform that you can run anywhere.
* [AWS Lambda support](docs/lambda/README.md)
* Easy to use
* Easy to scale
* Written in Go
* API Gateway built in
## What is Serverless/FaaS?
@@ -55,7 +57,7 @@ and you'll find plenty of information. We have pretty thorough post on the Iron.
## Join Our Community
First off, join the community!
Join our Slack community to get help and give feedback.
[![Slack Status](https://open-iron.herokuapp.com/badge.svg)](http://get.iron.io/open-slack)
@@ -63,24 +65,77 @@ First off, join the community!
This guide will get you up and running in a few minutes.
### Run IronFunctions Container
### Prequisites
To get started quickly with IronFunctions, you can just fire up an `iron/functions` container:
* Docker 1.10 or later installed and running
* Logged into Docker Hub (`docker login`)
### Run IronFunctions
To get started quickly with IronFunctions, just fire up an `iron/functions` container:
```sh
docker run --rm -it --name functions --privileged -v $PWD/data:/app/data -p 8080:8080 iron/functions
```
**Note**: A list of configurations via env variables can be found [here](docs/options.md).
This will start IronFunctions in single server mode, using an embedded database and message queue. You can find all the
configuration options [here](docs/options.md). If you are on Windows, see [windows](docs/operating/windows.md).
### CLI tool
The IronFunctions CLI tool is optional, but it makes things easier. Install it with:
Install the IronFunctions CLI tool:
```sh
curl -sSL http://get.iron.io/fnctl | sh
```
### Write a Function
Functions are small, bite sized bits of code that do one simple thing. Forget about monoliths when using functions,
just focus on the task that you want the function to perform.
The following is a Go function that just returns "Hello ${NAME}!":
```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)
}
```
Copy and paste the code above into a file called `hello.go`, then run:
```sh
# create func.yaml file, replace $USERNAME with your Docker Hub username.
fnctl init $USERNAME/hello
# build the function
fnctl build
# test it
fnctl run
# push it to Docker Hub
fnctl push
# create an app
fnctl apps create myapp
# create a route that maps /hello to your new function
fnctl routes create myapp /hello
```
You can find a bunch of examples in various languages in the [examples](examples/) directory. You can also
write your functions in AWS's [Lambda format](docs/lambda/README.md).
### Create an Application
An application is essentially a grouping of functions, that put together, form an API. Here's how to create an app.
@@ -99,7 +154,7 @@ curl -H "Content-Type: application/json" -X POST -d '{
[More on apps](docs/apps.md).
Now that we have an app, we can map routes to functions.
Now that we have an app, we can route endpoints to functions.
### Add a Route
@@ -209,13 +264,27 @@ Read more on [logging](docs/logging.md).
See [Writing Functions](docs/writing.md).
And you can find a bunch of examples in the [/examples](/examples) directory.
## More Documentation
See [docs/](docs/README.md) for full documentation.
## Want to contribute to IronFunctions?
## Roadmap
See [contributing](CONTRIBUTING.md).
These are the high level roadmap goals. See [milestones](https://github.com/iron-io/functions/milestones) for detailed issues.
* Alpha 1 - November 2016
* Initial release of base framework
* Lambda support
* Alpha 2 - December 2016
* Streaming input for hot containers #214
* Logging endpoint(s) for per function debugging #263
* Beta 1 - January 2017
* Smart Load Balancer #151
* Beta 2 - February 2017
* Cron like scheduler #100
* GA - March 2017
## Support
@@ -224,4 +293,8 @@ You can get community support via:
* [Stack Overflow](http://stackoverflow.com/questions/tagged/ironfunctions)
* [Slack](https://get.iron.io/open-slack)
You can get commercial support by contacting [Iron.io](https://iron.io)
You can get commercial support by contacting [Iron.io](https://iron.io/contact)
## Want to contribute to IronFunctions?
See [contributing](CONTRIBUTING.md).

View File

@@ -9,7 +9,6 @@ type App interface {
}
type Route interface {
// AppName() string `json:"appname"`
Path() string
Image() string
Headers() http.Header

View File

@@ -11,7 +11,7 @@ function build () {
function run () {
build
docker run --rm --privileged -it -e LOG_LEVEL=debug -e "DB_URL=bolt:///app/data/bolt.db" -v ${pwd}/data:/app/data -p 8080:8080 iron/functions
docker run --rm --name functions -it -v /var/run/docker.sock:/var/run/docker.sock -e LOG_LEVEL=debug -e "DB_URL=bolt:///app/data/bolt.db" -v $PWD/data:/app/data -p 8080:8080 iron/functions
}
switch ($cmd)

View File

@@ -10,6 +10,7 @@ If you are a developer using IronFunctions through the API, this section is for
* [fnctl (CLI Tool)](/fnctl/README.md)
* [Writing functions](writing.md)
* [Writing Lambda functions](docs/lambda/create.md)
* [Function file (func.yaml)](docs/function-file.md)
* [Packaging functions](packaging.md)
* [Open Function Format](function-format.md)
* [API Reference](https://app.swaggerhub.com/api/iron/functions/)

3
docs/assets/index.html Normal file
View File

@@ -0,0 +1,3 @@
<body>
<img src="logo-black-purple-400w.png"/>
</body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -10,9 +10,9 @@ base [function format](function-format.md).
Anywhere. Any cloud, on-premise, on your laptop. As long as you can run a Docker container, you can run IronFunctions.
## Which orchestration platforms does IronFunctions support?
## Which orchestration tools does IronFunctions support?
IronFunctions can run using any orchestration tool, any server
IronFunctions can be deployed using any orchestration tool.
## Does IronFunctions require Docker?

53
docs/function-file.md Normal file
View File

@@ -0,0 +1,53 @@
# Function files
Functions files are used to assist fnctl to help you when creating functions.
The files can be named as:
- func.yaml
- func.json
An example of a function file:
```yaml
name: iron/hello
version: 0.0.1
type: sync
memory: 128
config:
key: value
key2: value2
keyN: valueN
build:
- make
- make test
```
`app` (optional) is the application name to which this function will be pushed
to.
`image` is the name and tag to which this function will be pushed to and the
route updated to use it.
`route` (optional) allows you to overwrite the calculated route from the path
position. You may use it to override the calculated route.
`version` represents current version of the function. When publishing, it is
appended to the image as a tag.
`type` (optional) allows you to set the type of the route. `sync`, for functions
whose response are sent back to the requester; or `async`, for functions that
are started and return a task ID to customer while it executes in background.
Default: `sync`.
`memory` (optional) allows you to set a maximum memory threshold for this
function. If this function exceeds this limit during execution, it is stopped
and error message is logged. Default: `128`.
`config` (optional) is a set of configurations to be passed onto the route
setup. These configuration options shall override application configuration
during functions execution.
`build` (optional) is an array of shell calls which are used to helping building
the image. These calls are executed before `fnctl` calls `docker build` and
`docker push`.

View File

@@ -9,7 +9,7 @@ to use more production ready components.
Here's a rough diagram of what a production deployment looks like:
![IronFunctions Architecture Diagram](/docs/assets/architecture.svg)
![IronFunctions Architecture Diagram](../assets/architecture.png)
## Load Balancer

View File

@@ -7,7 +7,17 @@ Packaging a function has two parts:
Once it's pushed to a registry, you can use it by referencing it when adding a route.
## Creating an image
## Using fnctl
This is the easiest way to build, package and publish your functions.
##
### Creating an image
The basic Dockerfile for most languages is along these lines:
@@ -35,7 +45,7 @@ Or using [fnctl](../fnctl/README.md):
fnctl build
```
## Push your image
### Push your image
This part is simple:

View File

@@ -3,6 +3,8 @@
This will give you the basic overview of writing base level functions. You can also use higher level
abstractions that make it easier such as [lambda](lambda/README.md).
Also, for complete examples in various languages, see the [examples directory](/examples).
## Code
The most basic code layout in any language is as follows, this is pseudo code and is not meant to run.

9
examples/README.md Normal file
View File

@@ -0,0 +1,9 @@
# Example Functions
This directory has a collection of example functions you can look at to learn more about how to write them
or just copy one and build on it to get started faster.
## Hello World Examples
The [Hello World examples](hello/) are the most basic functions you can write and we'll try to have an example in most major languages.
This is a good place to start and good examples to copy and build upon.

View File

@@ -4,4 +4,4 @@ vendor/
/app
/__uberscript__
function.yaml
func.yaml

View File

@@ -3,22 +3,20 @@
This example will show you how to test and deploy Go (Golang) code to IronFunctions.
```sh
# create your func.yaml file
fnctl init <YOUR_DOCKERHUB_USERNAME>/hello
# build the function
fnctl build
# test it
cat hello.payload.json | fnctl run
# push it to Docker Hub
fnctl push
# Create a route to this function on IronFunctions
fnctl routes create myapp /hello YOUR_DOCKERHUB_USERNAME/hello:0.0.X
# todo: Image name could be optional if we read the function file for creating the route. Then command could be:
fnctl routes create myapp /hello
```
Now you use your function on IronFunctions:
Now you can call your function on IronFunctions:
```sh
curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/myapp/hello
```
Or surf to it: http://localhost:8080/r/myapp/hello

View File

@@ -0,0 +1,4 @@
name: treeder/hello4
version: 0.0.1
runtime: go
entrypoint: ./func

View File

@@ -13,5 +13,5 @@ type Person struct {
func main() {
p := &Person{Name: "World"}
json.NewDecoder(os.Stdin).Decode(p)
fmt.Println("Hello", p.Name, "!!!")
fmt.Printf("Hello %v!", p.Name)
}

View File

@@ -1,3 +1,3 @@
node_modules/
function.yaml
func.yaml
Dockerfile

View File

@@ -3,15 +3,15 @@
This example will show you how to test and deploy a Node function to IronFunctions.
```sh
# create your func.yaml file
fnctl init <YOUR_DOCKERHUB_USERNAME>/hello
# build the function
fnctl build
# test it
cat hello.payload.json | fnctl run
# push it to Docker Hub for use with IronFunctions
fnctl push
# Create a route to this function on IronFunctions
fnctl routes create myapp /hello YOUR_DOCKERHUB_USERNAME/hello:0.0.X
# todo: Image name could be optional if we read the function file for creating the route. Then command could be:
fnctl routes create myapp /hello
```

View File

@@ -0,0 +1,4 @@
name: treeder/node4
version: 0.0.2
runtime: node
entrypoint: node hello.js

View File

@@ -2,13 +2,14 @@
This example will show you how to test and deploy Go (Golang) code to IronFunctions.
### 1. Prepare the `functions.yaml` file:
### 1. Prepare the `func.yaml` file:
At functions.yaml you will find:
At func.yaml you will find:
```yml
app: phpapp
route: /hello
image: USERNAME/hello:0.0.1
image: USERNAME/hello
version: 0.0.1
build:
- docker run --rm -v "$PWD":/worker -w /worker iron/php:dev composer install
```

View File

@@ -2,13 +2,15 @@
This example will show you how to test and deploy Go (Golang) code to IronFunctions.
### 1. Prepare the `functions.yaml` file:
### 1. Prepare the `func.yaml` file:
At func.yaml you will find:
At functions.yaml you will find:
```yml
app: pythonapp
route: /hello
image: USERNAME/hello:0.0.1
image: USERNAME/hello
version: 0.0.1
build:
- docker run --rm -v "$PWD":/worker -w /worker iron/python:2-dev pip install -t packages -r requirements.txt
```

View File

@@ -1,16 +1,49 @@
# IronFunctions CLI
## Init
## Creating Functions
usage: fnctl init [--runtime node] [--entrypoint "node hello.js"] <name>
### init
Init will help you create a function.yaml file for the current directory.
Init will help you create a [function file](../docs/function-file.md) (func.yaml) in the current directory.
If there's a Dockerfile found, this will generate the basic file with just the image name.
It will then try to decipher the runtime based on the files in the current directory, if it can't figure it out, it will ask.
It will then take a best guess for what the entrypoint will be based on the language, it it can't guess, it will ask.
```sh
fnctl init [--runtime node] [--entrypoint "node hello.js"] <name>
```
## Basic
`--runtime` and `--entrypoint` are optional, init will try to figure out it out based on the files in the current directory.
If it can't figure it out, it will tell you.
If there's a Dockerfile found, it will use that as is
### Build, Bump, Run, Push
`fnctl` provides a few commands you'll use while creating and updating your functions: `build`, `bump`, `run` and `push`.
Build will build the image for your function.
```sh
fnctl build
```
Bump will bump the version number in your func.yaml file. Versions must be in [semver](http://semver.org/) format.
```sh
fnctl bump
```
Run will help you test your function. Functions read input from STDIN, so you can pipe the payload into the function like this:
```sh
cat `payload.json` | fnctl run
```
Push will push the function image to Docker Hub.
```sh
fnctl push
```
## Using the API
You can operate IronFunctions from the command line.
@@ -40,6 +73,47 @@ $ fnctl routes delete otherapp hello # delete route
/hello deleted
```
## Application level configuration
When creating an application, you can configure it to tweak its behavior and its
routes' with an appropriate flag, `config`.
Thus a more complete example of an application creation will look like:
```sh
fnctl apps create --config DB_URL=http://example.org/ otherapp
```
`--config` is a map of values passed to the route runtime in the form of
environment variables prefixed with `CONFIG_`.
Repeated calls to `fnctl apps create` will trigger an update of the given
route, thus you will be able to change any of these attributes later in time
if necessary.
## Route level configuration
When creating a route, you can configure it to tweak its behavior, the possible
choices are: `memory`, `type` and `config`.
Thus a more complete example of route creation will look like:
```sh
fnctl routes create --memory 256 --type async --config DB_URL=http://example.org/ otherapp /hello iron/hello
```
`--memory` is number of usable MiB for this function. If during the execution it
exceeds this maximum threshold, it will halt and return an error in the logs.
`--type` is the type of the function. Either `sync`, in which the client waits
until the request is successfully completed, or `async`, in which the clients
dispatches a new request, gets a task ID back and closes the HTTP connection.
`--config` is a map of values passed to the route runtime in the form of
environment variables prefixed with `CONFIG_`.
Repeated calls to `fnctl route create` will trigger an update of the given
route, thus you will be able to change any of these attributes later in time
if necessary.
## Changing target host
`fnctl` is configured by default to talk http://localhost:8080.
@@ -101,142 +175,11 @@ It means that first subdirectory are always considered app names (e.g. `myapp`
and `other`), each subdirectory of these firsts are considered part of the route
(e.g. `route1/subroute1`).
`fnctl update` expects that each directory to contain a file `functions.yaml`
`fnctl update` expects that each directory to contain a file `func.yaml`
which instructs `fnctl` on how to act with that particular update, and a
Dockerfile which it is going to use to build the image and push to Docker Hub.
## Functions files (functions.yaml)
Functions files are used to assist fnctl to execute bulk updates of your
functions. The files can be named as:
- functions.yaml
- functions.yml
- function.yaml
- function.yml
- functions.json
- function.json
- fn.yaml
- fn.yml
- fn.json
An example of a function file:
```yaml
app: myapp
name: iron/hello
route: "/custom/route"
version: 0.0.1
type: sync
memory: 128
config:
key: value
key2: value2
keyN: valueN
build:
- make
- make test
```
`app` (optional) is the application name to which this function will be pushed
to.
`image` is the name and tag to which this function will be pushed to and the
route updated to use it.
`route` (optional) allows you to overwrite the calculated route from the path
position. You may use it to override the calculated route.
`version` represents current version of the function. When publishing, it is
appended to the image as a tag.
`type` (optional) allows you to set the type of the route. `sync`, for functions
whose response are sent back to the requester; or `async`, for functions that
are started and return a task ID to customer while it executes in background.
Default: `sync`.
`memory` (optional) allows you to set a maximum memory threshold for this
function. If this function exceeds this limit during execution, it is stopped
and error message is logged. Default: `128`.
`config` (optional) is a set of configurations to be passed onto the route
setup. These configuration options shall override application configuration
during functions execution.
`build` (optional) is an array of shell calls which are used to helping building
the image. These calls are executed before `fnctl` calls `docker build` and
`docker push`.
## Build, Bump, Push
When dealing with a lot of functions you might find yourself making lots of
individual calls. `fnctl` offers two command to help you with that: `build` and
`bump`.
```sh
$ fnctl build
path result
/app/hello done
/app/test done
```
`fnctl build` is similar to `publish` except it neither publishes the resulting
docker image to Docker Hub nor updates the routes in IronFunctions server.
```sh
$ fnctl bump
path result
/app/hello done
/app/test done
```
`fnctl bump` will scan all IronFunctions whose `version` key in function file
follows [semver](http://semver.org/) rules and bump their version according.
`fnctl push` will scan all IronFunctions and push their images to Docker Hub,
and update their routes accordingly.
## Application level configuration
When creating an application, you can configure it to tweak its behavior and its
routes' with an appropriate flag, `config`.
Thus a more complete example of an application creation will look like:
```sh
fnctl apps create --config DB_URL=http://example.org/ otherapp
```
`--config` is a map of values passed to the route runtime in the form of
environment variables prefixed with `CONFIG_`.
Repeated calls to `fnctl apps create` will trigger an update of the given
route, thus you will be able to change any of these attributes later in time
if necessary.
## Route level configuration
When creating a route, you can configure it to tweak its behavior, the possible
choices are: `memory`, `type` and `config`.
Thus a more complete example of route creation will look like:
```sh
fnctl routes create --memory 256 --type async --config DB_URL=http://example.org/ otherapp /hello iron/hello
```
`--memory` is number of usable MiB for this function. If during the execution it
exceeds this maximum threshold, it will halt and return an error in the logs.
`--type` is the type of the function. Either `sync`, in which the client waits
until the request is successfully completed, or `async`, in which the clients
dispatches a new request, gets a task ID back and closes the HTTP connection.
`--config` is a map of values passed to the route runtime in the form of
environment variables prefixed with `CONFIG_`.
Repeated calls to `fnctl route create` will trigger an update of the given
route, thus you will be able to change any of these attributes later in time
if necessary.
## Build
## Contributing
Ensure you have Go configured and installed in your environment. Once it is
done, run:

View File

@@ -1,13 +1,13 @@
package main
type NotFoundError struct {
type notFoundError struct {
S string
}
func (e *NotFoundError) Error() string {
func (e *notFoundError) Error() string {
return e.S
}
func newNotFoundError(s string) *NotFoundError {
return &NotFoundError{S: s}
func newNotFoundError(s string) *notFoundError {
return &notFoundError{S: s}
}

View File

@@ -75,7 +75,7 @@ func initFn() cli.Command {
func (a *initFnCmd) init(c *cli.Context) error {
if !a.force {
ff, err := findFuncfile()
if _, ok := err.(*NotFoundError); !ok && err != nil {
if _, ok := err.(*notFoundError); !ok && err != nil {
return err
}
if ff != nil {

View File

@@ -38,7 +38,7 @@ func (r *runCmd) run(c *cli.Context) error {
if image == "" {
ff, err := findFuncfile()
if err != nil {
if _, ok := err.(*NotFoundError); ok {
if _, ok := err.(*notFoundError); ok {
return errors.New("error: image name is missing or no function file found")
} else {
return err