# IronFunctions CLI ## Build Ensure you have Go configured and installed in your environment. Once it is done, run: ```sh $ make ``` It will build fnctl compatible with your local environment. You can test this CLI, right away with: ```sh $ ./fnctl ``` ## Basic You can operate IronFunctions from the command line. ```sh $ fnctl apps # list apps myapp $ fnctl apps create otherapp # create new app otherapp created $ fnctl apps describe otherapp # describe an app app: otherapp no specific configuration $ fnctl apps myapp otherapp $ fnctl routes myapp # list routes of an app path image /hello iron/hello $ fnctl routes create otherapp /hello iron/hello # create route /hello created with iron/hello $ fnctl routes delete otherapp hello # delete route /hello deleted ``` ## Changing target host `fnctl` is configured by default to talk to a locally installed IronFunctions. You may reconfigure it to talk to a remote installation by updating a local environment variable (`$API_URL`): ```sh $ export API_URL="http://myfunctions.example.org/" $ fnctl ... ``` ## Publish Also there is the publish command that is going to scan all local directory for functions, rebuild them and push them to Docker Hub and update them in IronFunction. ```sh $ fnctl publish path result /app/hello done /app/hello-sync error: no Dockerfile found for this function /app/test done ``` It works by scanning all children directories of the current working directory, following this convention:
┌───────┐
│  ./   │
└───┬───┘
    │     ┌───────┐
    ├────▶│ myapp │
    │     └───┬───┘
    │         │     ┌───────┐
    │         ├────▶│route1 │
    │         │     └───────┘
    │         │         │     ┌─────────┐
    │         │         ├────▶│subroute1│
    │         │         │     └─────────┘
    │
    │     ┌───────┐
    ├────▶│ other │
    │     └───┬───┘
    │         │     ┌───────┐
    │         ├────▶│route1 │
    │         │     └───────┘
It will render this pattern of updates: ```sh $ fnctl publish path result /myapp/route1/subroute1 done /other/route1 done ``` 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` 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 image: iron/hello route: "/custom/route" 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. `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 for files named `VERSION` and bump their version according to [semver](http://semver.org/) rules. In their absence, it will skip. `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.