From 1c58b245333983b6c33589156177c25433db505b Mon Sep 17 00:00:00 2001 From: Chad Arimura Date: Wed, 24 May 2017 21:21:53 -0700 Subject: [PATCH 01/17] readme updates, added ascii to create issue #33 --- Gopkg.lock | 26 +++++++++++++------------- README.md | 42 ++++++++++++------------------------------ fn/Gopkg.toml | 1 + fn/apps.go | 15 ++++++++++++++- 4 files changed, 40 insertions(+), 44 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index bfc551e31..8c11b20c6 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1,4 +1,4 @@ -memo = "aed9e667c6720b5c2b6c83fdc3968091b09ca0d48df951b424c2173b28c196a9" +memo = "bd1e1a24b7655bd27880d6b3d752e400a4e36e7b1d7129a1a9e54a11fac75c9c" [[projects]] branch = "master" @@ -15,8 +15,8 @@ memo = "aed9e667c6720b5c2b6c83fdc3968091b09ca0d48df951b424c2173b28c196a9" [[projects]] name = "github.com/Microsoft/go-winio" packages = ["."] - revision = "706941bedd2d9b3a8c88e4022bd0078101f233f2" - version = "v0.4.1" + revision = "f533f7a102197536779ea3a8cb881d639e21ec5a" + version = "v0.4.2" [[projects]] branch = "master" @@ -58,7 +58,7 @@ memo = "aed9e667c6720b5c2b6c83fdc3968091b09ca0d48df951b424c2173b28c196a9" branch = "master" name = "github.com/aws/aws-sdk-go" packages = ["aws","aws/awserr","aws/awsutil","aws/client","aws/client/metadata","aws/corehandlers","aws/credentials","aws/credentials/ec2rolecreds","aws/credentials/endpointcreds","aws/credentials/stscreds","aws/defaults","aws/ec2metadata","aws/endpoints","aws/request","aws/session","aws/signer/v4","private/protocol","private/protocol/json/jsonutil","private/protocol/jsonrpc","private/protocol/query","private/protocol/query/queryutil","private/protocol/rest","private/protocol/restjson","private/protocol/xml/xmlutil","service/lambda","service/sts"] - revision = "31484500fe77b88dbe197c6348358ed275aed5d7" + revision = "0bc99f4aa1cf50245de234b1ce0b33463a3ad5fe" [[projects]] branch = "master" @@ -124,7 +124,7 @@ memo = "aed9e667c6720b5c2b6c83fdc3968091b09ca0d48df951b424c2173b28c196a9" branch = "master" name = "github.com/docker/cli" packages = ["cli/config/configfile"] - revision = "883d28cfce55c2eac049b724b2cedcae2ad4bd0c" + revision = "11e7d35f9c94a51f1a8c3056e1f386c8533b1b28" [[projects]] name = "github.com/docker/distribution" @@ -268,7 +268,7 @@ memo = "aed9e667c6720b5c2b6c83fdc3968091b09ca0d48df951b424c2173b28c196a9" branch = "master" name = "github.com/golang/protobuf" packages = ["proto"] - revision = "fec3b39b059c0f88fa6b20f5ed012b1aa203a8b4" + revision = "7a211bcf3bce0e3f1d74f9894916e6f116ae83b4" [[projects]] branch = "master" @@ -310,7 +310,7 @@ memo = "aed9e667c6720b5c2b6c83fdc3968091b09ca0d48df951b424c2173b28c196a9" branch = "master" name = "github.com/heroku/docker-registry-client" packages = ["registry"] - revision = "296b6e48681ccdb6e4f22a489afdab8aca704697" + revision = "3c06de30ae876abceef9a2101c83cc022df53199" source = "https://github.com/treeder/docker-registry-client.git" [[projects]] @@ -377,13 +377,13 @@ memo = "aed9e667c6720b5c2b6c83fdc3968091b09ca0d48df951b424c2173b28c196a9" branch = "master" name = "github.com/mitchellh/mapstructure" packages = ["."] - revision = "cc8532a8e9a55ea36402aa21efdf403a60d34096" + revision = "d0303fe809921458f417bcf828397a65db30a7e4" [[projects]] branch = "master" name = "github.com/moby/moby" packages = ["pkg/jsonmessage"] - revision = "a9ff628a3c7c55cf016af88f37c4fb6a6029e17a" + revision = "da3c3ec1458588d5d263dc3babd3dca95fdc7d8d" [[projects]] name = "github.com/opencontainers/go-digest" @@ -443,7 +443,7 @@ memo = "aed9e667c6720b5c2b6c83fdc3968091b09ca0d48df951b424c2173b28c196a9" branch = "master" name = "github.com/spf13/jwalterweatherman" packages = ["."] - revision = "8f07c835e5cc1450c082fe3a439cf87b0cbb2d99" + revision = "0efa5202c04663c757d84f90f5219c1250baf94f" [[projects]] branch = "master" @@ -473,19 +473,19 @@ memo = "aed9e667c6720b5c2b6c83fdc3968091b09ca0d48df951b424c2173b28c196a9" branch = "master" name = "golang.org/x/crypto" packages = ["bcrypt","blowfish"] - revision = "6c586e17d90a7d08bbbc4069984180dce3b04117" + revision = "7e9105388ebff089b3f99f0ef676ea55a6da3a7e" [[projects]] branch = "master" name = "golang.org/x/net" packages = ["context","context/ctxhttp","idna","proxy","publicsuffix"] - revision = "0d772244c73d752bbe0c729ff997a09d6a6fdaf1" + revision = "7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6" [[projects]] branch = "master" name = "golang.org/x/sys" packages = ["unix","windows"] - revision = "dbc2be9168a660ef302e04b6ff6406de6f967473" + revision = "a55a76086885b80f79961eacb876ebd8caf3868d" [[projects]] branch = "master" diff --git a/README.md b/README.md index 4d982d43e..f8935c210 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ -# NONAME... :( +# Oracle Functions -[![CircleCI](https://circleci.com/gh/treeder/functions.svg?style=svg)](https://circleci.com/gh/treeder/functions) [![GoDoc](https://godoc.org/github.com/treeder/functions?status.svg)](https://godoc.org/github.com/treeder/functions) Welcome to Oracle Functions! The open source serverless platform. @@ -24,26 +23,27 @@ Service (FaaS) platform that you can run anywhere. TODO: Slack or Discord community. -## Quickstart - -This guide will get you up and running in a few minutes. - -### Prequisites +## Prequisites * Docker 17.05 or later installed and running * Logged into Docker Hub (`docker login`) -# UNTIL THIS IS PUBLIC, YOU'LL NEED TO BUILD AND RUN THE CODE FROM THIS REPO +## Installation + +The following instructions apply while the project is a private repo. They'll +build Oracle Functions and the CLI tool directly from the repo instead of +using pre-built containers. Will be much easier once public. ```sh -# install cli tool +# Build and Install CLI tool cd fn make dep # just once make install -# Start server: + +# Build and Run Functions Server cd .. make dep # just once -make run +make run # will build as well ``` -Welcome to Oracle Functions! The open source serverless platform. - -## What is Oracle Functions? - -Oracle Functions is an open source [serverless](serverless.md) platform, or as we like to refer to it, Functions as a -Service (FaaS) platform that you can run anywhere. +Oracle Functions is an open source [serverless](serverless.md) platform, or as we like to refer to it, Functions as a Service (FaaS) platform that you can run anywhere. Some of it's key features: * Write once * [Any language](docs/faq.md#which-languages-are-supported) @@ -19,20 +14,19 @@ Service (FaaS) platform that you can run anywhere. * Easy to manage [for operators](docs/README.md#for-operators) * Written in [Go](https://golang.org) -## Join Our Community - -TODO: Slack or Discord community. ## Prequisites * Docker 17.05 or later installed and running * Logged into Docker Hub (`docker login`) -## Installation +## Usage -The following instructions apply while the project is a private repo. They'll -build Oracle Functions and the CLI tool directly from the repo instead of -using pre-built containers. Will be much easier once public. +### Installation + +NOTE: The following instructions apply while the project is a private repo. This will +build the Functions server and the CLI tool directly from the repo instead of +using pre-built containers. Once the project is public, these steps will be unnecessary. ```sh # Build and Install CLI tool @@ -71,63 +65,75 @@ configuration options [here](docs/operating/options.md). If you are on Windows, --> -### Write a Function +### Writing Your First 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. +Functions are small but powerful blocks of code that generally 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}!": +Start with this readme tutorial, and then you can learn more about function best practices in +our section [Writing Functions](docs/writing.md). + +The following is a simple Go program that outputs a string to STDOUT. Copy and paste the code below into a file called `func.go`. ```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) + fmt.Println("Boom. Oracle Functions.") } ``` -Copy and paste the code above into a file called `func.go`, then run the following commands to build your function -and deploy it. +Now run the following commands to build your function and deploy it: ```sh -# Initilize your function, replace $USERNAME with your Docker Hub username. -fn init $USERNAME/hello -# Test it - you can pass data into it too by piping it in, eg: `cat hello.payload.json | fn run` -fn run -# Once it's ready, deploy it to your functions server (default localhost:8080) +# Create your first application fn apps create myapp + +# Initilizes your function w/ prebuilt func.yaml +# Replace $USERNAME with your DockerHub username +fn init $USERNAME/hello + +# Test your function +# This will run inside a container exactly how it will on the server +fn run + +# Deploy it to your functions server (default localhost:8080) +# This will create a route to your function as well fn deploy myapp ``` -Now you can call your function: +Boom. Now you can call your function: ```sh curl http://localhost:8080/r/myapp/hello ``` -Or surf to it: http://localhost:8080/r/myapp/hello +Or in a browser: [http://localhost:8080/r/myapp/hello](http://localhost:8080/r/myapp/hello) -To update your function: +That's it! You just deployed your first function and called it. Now to update your function +you can update your code and run ```fn deploy myapp``` again. -```sh -# Just update your code and run: -fn deploy myapp -``` +## Learning More + +### Documentation + +See [docs/](docs/README.md) for full documentation. + +More on [Writing Functions](docs/writing.md). + +And you can find a bunch of examples in the [/examples](/examples) directory. + +You can also write your functions in AWS's [Lambda format](docs/lambda/README.md). + +### Get Involved + +TODO: Slack or Discord community. + +See [contributing](CONTRIBUTING.md). -See the [documentation](docs/README.md) for more information. And 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). ## Functions UI @@ -137,21 +143,9 @@ docker run --rm -it --link functions:api -p 4000:4000 -e "API_URL=http://api:808 For more information, see: https://github.com/treeder/functions-ui -## Writing Functions - -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. ## Roadmap See [milestones](https://gitlab.oracledx.com/odx/functions/milestones) for detailed issues. -## Want to contribute to Oracle Functions? - -See [contributing](CONTRIBUTING.md). From a565c09c7fa47217c62b65ae432690e28a43ed6e Mon Sep 17 00:00:00 2001 From: Chad Arimura Date: Thu, 25 May 2017 14:28:00 -0700 Subject: [PATCH 04/17] reorging examples/tutorials a bit --- Gopkg.lock | 2 +- README.md | 59 +++++++++++------------- examples/README.md | 8 ++-- examples/hello/go/.gitignore | 7 --- examples/hello/go/README.md | 27 ----------- examples/hello/go/func.go | 17 ------- examples/hello/go/hello.payload.json | 3 -- examples/hello/node/.gitignore | 3 -- examples/hello/node/README.md | 41 ---------------- examples/hello/node/func.js | 9 ---- examples/hello/node/hello.payload.json | 3 -- examples/hello/node/package.json | 7 --- examples/hello/php/.gitignore | 1 - examples/hello/php/Dockerfile | 6 --- examples/hello/php/README.md | 48 ------------------- examples/hello/php/composer.json | 4 -- examples/hello/php/func.yaml | 5 -- examples/hello/php/hello.payload.json | 3 -- examples/hello/php/hello.php | 10 ---- examples/hello/python/.gitignore | 2 - examples/hello/python/Dockerfile | 6 --- examples/hello/python/README.md | 48 ------------------- examples/hello/python/hello.payload.json | 3 -- examples/hello/python/hello.py | 12 ----- examples/hello/python/requirements.txt | 0 examples/hello/ruby/.gitignore | 5 -- examples/hello/ruby/Gemfile | 4 -- examples/hello/ruby/README.md | 44 ------------------ examples/hello/ruby/func.rb | 12 ----- examples/hello/ruby/hello.payload.json | 3 -- examples/hello/rust/Cargo.toml | 6 --- examples/hello/rust/README.md | 33 ------------- examples/hello/rust/src/main.rs | 10 ---- examples/hotfunctions/http/func.go | 45 ------------------ examples/hotfunctions/http/hotroute.json | 9 ---- fn/init.go | 11 +++-- 36 files changed, 37 insertions(+), 479 deletions(-) delete mode 100644 examples/hello/go/.gitignore delete mode 100644 examples/hello/go/README.md delete mode 100644 examples/hello/go/func.go delete mode 100644 examples/hello/go/hello.payload.json delete mode 100644 examples/hello/node/.gitignore delete mode 100644 examples/hello/node/README.md delete mode 100644 examples/hello/node/func.js delete mode 100644 examples/hello/node/hello.payload.json delete mode 100644 examples/hello/node/package.json delete mode 100644 examples/hello/php/.gitignore delete mode 100644 examples/hello/php/Dockerfile delete mode 100644 examples/hello/php/README.md delete mode 100644 examples/hello/php/composer.json delete mode 100644 examples/hello/php/func.yaml delete mode 100644 examples/hello/php/hello.payload.json delete mode 100644 examples/hello/php/hello.php delete mode 100644 examples/hello/python/.gitignore delete mode 100644 examples/hello/python/Dockerfile delete mode 100644 examples/hello/python/README.md delete mode 100644 examples/hello/python/hello.payload.json delete mode 100644 examples/hello/python/hello.py delete mode 100644 examples/hello/python/requirements.txt delete mode 100644 examples/hello/ruby/.gitignore delete mode 100644 examples/hello/ruby/Gemfile delete mode 100644 examples/hello/ruby/README.md delete mode 100644 examples/hello/ruby/func.rb delete mode 100644 examples/hello/ruby/hello.payload.json delete mode 100644 examples/hello/rust/Cargo.toml delete mode 100644 examples/hello/rust/README.md delete mode 100644 examples/hello/rust/src/main.rs delete mode 100644 examples/hotfunctions/http/func.go delete mode 100644 examples/hotfunctions/http/hotroute.json diff --git a/Gopkg.lock b/Gopkg.lock index 8c11b20c6..a915373dc 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -383,7 +383,7 @@ memo = "bd1e1a24b7655bd27880d6b3d752e400a4e36e7b1d7129a1a9e54a11fac75c9c" branch = "master" name = "github.com/moby/moby" packages = ["pkg/jsonmessage"] - revision = "da3c3ec1458588d5d263dc3babd3dca95fdc7d8d" + revision = "e925820bfd5af066497800a02c597d6846988398" [[projects]] name = "github.com/opencontainers/go-digest" diff --git a/README.md b/README.md index 72585ef52..cb2338358 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,8 @@ -Oracle Functions is an open source [serverless](serverless.md) platform, or as we like to refer to it, Functions as a Service (FaaS) platform that you can run anywhere. Some of it's key features: +Oracle Functions is an event-driven, open source, [functions-as-a-service](serverless.md) compute +platform that you can run anywhere. Some of it's key features: * Write once * [Any language](docs/faq.md#which-languages-are-supported) @@ -13,6 +14,7 @@ Oracle Functions is an open source [serverless](serverless.md) platform, or as w * Easy to use [for developers](docs/README.md#for-developers) * Easy to manage [for operators](docs/README.md#for-operators) * Written in [Go](https://golang.org) +* Simple yet powerful extensibility ## Prequisites @@ -65,14 +67,11 @@ configuration options [here](docs/operating/options.md). If you are on Windows, --> -### Writing Your First Function +### Your First Function Functions are small but powerful blocks of code that generally do one simple thing. Forget about monoliths when using functions, just focus on the task that you want the function to perform. -Start with this readme tutorial, and then you can learn more about function best practices in -our section [Writing Functions](docs/writing.md). - -The following is a simple Go program that outputs a string to STDOUT. Copy and paste the code below into a file called `func.go`. +The following is a simple Go program that outputs a string to STDOUT. Copy and paste the code below into a file called `func.go`. Currently the function must be named func.your_language_extention (ie func.go, func.js, etc.) ```go package main @@ -82,30 +81,30 @@ import ( ) func main() { - fmt.Println("Boom. Oracle Functions.") + fmt.Println("Hello from Oracle Functions!") } ``` -Now run the following commands to build your function and deploy it: +Now run the following CLI commands: ```sh # Create your first application fn apps create myapp -# Initilizes your function w/ prebuilt func.yaml -# Replace $USERNAME with your DockerHub username -fn init $USERNAME/hello +# Initialize your function +# This detects your runtime from the code above and creates a func.yaml +fn init /hello # Test your function # This will run inside a container exactly how it will on the server fn run -# Deploy it to your functions server (default localhost:8080) +# Deploy your functions to the Oracle Functions server (default localhost:8080) # This will create a route to your function as well fn deploy myapp ``` -Boom. Now you can call your function: +Now you can call your function: ```sh curl http://localhost:8080/r/myapp/hello @@ -116,36 +115,32 @@ Or in a browser: [http://localhost:8080/r/myapp/hello](http://localhost:8080/r/m That's it! You just deployed your first function and called it. Now to update your function you can update your code and run ```fn deploy myapp``` again. -## Learning More +## To Learn More -### Documentation +- Walk through the following [tutorial series](docs/tutorial) +- See our [full documentation](docs/README.md) +- View our [examples directory](/examples) +- You can also write your functions in AWS [Lambda format](docs/lambda/README.md) -See [docs/](docs/README.md) for full documentation. +## Get Involved -More on [Writing Functions](docs/writing.md). - -And you can find a bunch of examples in the [/examples](/examples) directory. - -You can also write your functions in AWS's [Lambda format](docs/lambda/README.md). - -### Get Involved - -TODO: Slack or Discord community. - -See [contributing](CONTRIBUTING.md). +- TODO: Slack or Discord community +- Learn how to [contribute](CONTRIBUTING.md) +- See [milestones](https://gitlab.oracledx.com/odx/functions/milestones) for detailed issues -## Functions UI +## User Interface + +This is the graphical user interface for Oracle Functions. It is currently not buildable. ```sh docker run --rm -it --link functions:api -p 4000:4000 -e "API_URL=http://api:8080" treeder/functions-ui ``` -For more information, see: https://github.com/treeder/functions-ui +For more information, see: [https://github.com/treeder/functions-ui](https://github.com/treeder/functions-ui) -## Roadmap - -See [milestones](https://gitlab.oracledx.com/odx/functions/milestones) for detailed issues. +## Next up: Walk through the following [tutorial series](docs/tutorial/) --> + diff --git a/examples/README.md b/examples/README.md index 3b6ea228f..135c2daf1 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,9 +1,7 @@ # 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. +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 +## Tutorial Series -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. +The [Tutorial Series](tutorial/) will demonstrate some of Oracle Functions capabilities through a series of exmaples. We'll try to examples in most major languages. This is a great place to start! diff --git a/examples/hello/go/.gitignore b/examples/hello/go/.gitignore deleted file mode 100644 index 47868d339..000000000 --- a/examples/hello/go/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -vendor/ -/hello -/go -/app -/__uberscript__ - -func.yaml diff --git a/examples/hello/go/README.md b/examples/hello/go/README.md deleted file mode 100644 index ced7b8d99..000000000 --- a/examples/hello/go/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Quick Example for a Go Function (3 minutes) - -This example will show you how to test and deploy Go (Golang) code to Oracle Functions. - -```sh -# create your func.yaml file -fn init /hello -# build the function -fn build -# test it -cat hello.payload.json | fn run -# push it to Docker Hub -fn push -# Create a route to this function on Oracle Functions -fn routes create myapp /hello -``` - -Now you can call your function on Oracle Functions: - -```sh -curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/myapp/hello -``` - -## Dependencies - -Be sure you're dependencies are in the `vendor/` directory and that's it. - diff --git a/examples/hello/go/func.go b/examples/hello/go/func.go deleted file mode 100644 index bf0518407..000000000 --- a/examples/hello/go/func.go +++ /dev/null @@ -1,17 +0,0 @@ -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) -} diff --git a/examples/hello/go/hello.payload.json b/examples/hello/go/hello.payload.json deleted file mode 100644 index 97e136b69..000000000 --- a/examples/hello/go/hello.payload.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "Johnny" -} diff --git a/examples/hello/node/.gitignore b/examples/hello/node/.gitignore deleted file mode 100644 index 8977e475d..000000000 --- a/examples/hello/node/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules/ -func.yaml -Dockerfile diff --git a/examples/hello/node/README.md b/examples/hello/node/README.md deleted file mode 100644 index 2a4baff97..000000000 --- a/examples/hello/node/README.md +++ /dev/null @@ -1,41 +0,0 @@ -## Quick Example for a NodeJS Function (4 minutes) - -This example will show you how to test and deploy a Node function to Oracle Functions. - -```sh -# create your func.yaml file -fn init /hello -# build the function -fn build -# test it -cat hello.payload.json | fn run -# push it to Docker Hub -fn push -# Create a route to this function on Oracle Functions -fn routes create myapp /hello -``` - -Now surf to: http://localhost:8080/r/myapp/hello - -## Dependencies - -Create a [package.json](https://docs.npmjs.com/getting-started/using-a-package.json) file in your functions directory. - -Run: - -```sh -docker run --rm -v "$PWD":/function -w /function funcy/node:dev npm install -``` - -Then everything should work. - -For example, using the `package.json` file in this directory which includes the [request](https://www.npmjs.com/package/request) package, you can add this to func.js and it will work: - -```js -var request = require('request'); -request('http://www.google.com', function (error, response, body) { - if (!error && response.statusCode == 200) { - console.log(body) // Show the HTML for the Google homepage. - } -}) -``` diff --git a/examples/hello/node/func.js b/examples/hello/node/func.js deleted file mode 100644 index 356544e81..000000000 --- a/examples/hello/node/func.js +++ /dev/null @@ -1,9 +0,0 @@ -name = "World"; -fs = require('fs'); -try { - obj = JSON.parse(fs.readFileSync('/dev/stdin').toString()) - if (obj.name != "") { - name = obj.name - } -} catch(e) {} -console.log("Hello", name, "from Node!"); diff --git a/examples/hello/node/hello.payload.json b/examples/hello/node/hello.payload.json deleted file mode 100644 index 97e136b69..000000000 --- a/examples/hello/node/hello.payload.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "Johnny" -} diff --git a/examples/hello/node/package.json b/examples/hello/node/package.json deleted file mode 100644 index f332baddb..000000000 --- a/examples/hello/node/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "my-awesome-func", - "version": "1.0.0", - "dependencies": { - "request": "^2.78.0" - } -} \ No newline at end of file diff --git a/examples/hello/php/.gitignore b/examples/hello/php/.gitignore deleted file mode 100644 index 48b8bf907..000000000 --- a/examples/hello/php/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vendor/ diff --git a/examples/hello/php/Dockerfile b/examples/hello/php/Dockerfile deleted file mode 100644 index 1da497e06..000000000 --- a/examples/hello/php/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM funcy/php - -WORKDIR /app -ADD . /app - -ENTRYPOINT ["php", "hello.php"] diff --git a/examples/hello/php/README.md b/examples/hello/php/README.md deleted file mode 100644 index 1ccc9b1d1..000000000 --- a/examples/hello/php/README.md +++ /dev/null @@ -1,48 +0,0 @@ -## Quick Example for a PHP Function (4 minutes) - -This example will show you how to test and deploy Go (Golang) code to Oracle Functions. - -### 1. Prepare the `func.yaml` file: - -At func.yaml you will find: - -```yml -name: USERNAME/hello -version: 0.0.1 -path: /hello -build: -- docker run --rm -v "$PWD":/worker -w /worker funcy/php:dev composer install -``` - -The important step here is to ensure you replace `USERNAME` with your Docker Hub account name. Some points of note: -the application name is `phpapp` and the route for incoming requests is `/hello`. These informations are relevant for -the moment you try to test this function. - -### 2. Build: - -```sh -# build the function -fn build -# test it -cat hello.payload.json | fn run -# push it to Docker Hub -fn push -# Create a route to this function on Oracle Functions -fn routes create phpapp /hello -``` - -`-v` is optional, but it allows you to see how this function is being built. - -### 3. Queue jobs for your function - -Now you can start jobs on your function. Let's quickly queue up a job to try it out. - -```sh -cat hello.payload.json | fn call phpapp /hello -``` - -Here's a curl example to show how easy it is to do in any language: - -```sh -curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/phpapp/hello -``` \ No newline at end of file diff --git a/examples/hello/php/composer.json b/examples/hello/php/composer.json deleted file mode 100644 index df8dd9cf8..000000000 --- a/examples/hello/php/composer.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "require": { - } -} diff --git a/examples/hello/php/func.yaml b/examples/hello/php/func.yaml deleted file mode 100644 index 027b012ee..000000000 --- a/examples/hello/php/func.yaml +++ /dev/null @@ -1,5 +0,0 @@ -name: USERNAME/hello -version: 0.0.1 -path: /hello -build: -- docker run --rm -v "$PWD":/worker -w /worker funcy/php:dev composer install diff --git a/examples/hello/php/hello.payload.json b/examples/hello/php/hello.payload.json deleted file mode 100644 index 97e136b69..000000000 --- a/examples/hello/php/hello.payload.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "Johnny" -} diff --git a/examples/hello/php/hello.php b/examples/hello/php/hello.php deleted file mode 100644 index 7828f1f95..000000000 --- a/examples/hello/php/hello.php +++ /dev/null @@ -1,10 +0,0 @@ - 0.14.0' -gem 'json', '> 1.8.2' diff --git a/examples/hello/ruby/README.md b/examples/hello/ruby/README.md deleted file mode 100644 index 05ef81eea..000000000 --- a/examples/hello/ruby/README.md +++ /dev/null @@ -1,44 +0,0 @@ -## Quick Example for a Ruby Function (4 minutes) - -This example will show you how to test and deploy a Ruby function to Oracle Functions. - -```sh -# create your func.yaml file -fn init /hello -# install dependencies, we need the json gem to run this -docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle install --standalone --clean -# build the function -fn build -# test it -cat hello.payload.json | fn run -# push it to Docker Hub -fn push -# Create a route to this function on Oracle Functions -fn routes create myapp /hello -``` - -Now surf to: http://localhost:8080/r/myapp/hello - -## Dependencies - -Create a [Gemfile](http://bundler.io/gemfile.html) file in your function directory, then run: - -```sh -docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle install --standalone --clean -``` - -Ruby doesn't pick up the gems automatically, so you'll have to add this to the top of your `func.rb` file: - -```ruby -require_relative 'bundle/bundler/setup' -``` - -Open `func.rb` to see it in action. - -To update dependencies: - -```sh -docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle update -# then install again to vendor them -docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle update -``` diff --git a/examples/hello/ruby/func.rb b/examples/hello/ruby/func.rb deleted file mode 100644 index a16a04030..000000000 --- a/examples/hello/ruby/func.rb +++ /dev/null @@ -1,12 +0,0 @@ -require_relative 'bundle/bundler/setup' -require 'json' - -name = "World" - -payload = STDIN.read -if payload != "" - payload = JSON.parse(payload) - name = payload['name'] -end - -puts "Hello #{name} from Ruby!" diff --git a/examples/hello/ruby/hello.payload.json b/examples/hello/ruby/hello.payload.json deleted file mode 100644 index 97e136b69..000000000 --- a/examples/hello/ruby/hello.payload.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "Johnny" -} diff --git a/examples/hello/rust/Cargo.toml b/examples/hello/rust/Cargo.toml deleted file mode 100644 index 7c3608e1d..000000000 --- a/examples/hello/rust/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "func" -version = "0.1.0" -authors = ["Seif Lotfy "] - -[dependencies] diff --git a/examples/hello/rust/README.md b/examples/hello/rust/README.md deleted file mode 100644 index 895f3ba51..000000000 --- a/examples/hello/rust/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# Using rust with functions - -The easiest way to create a function in rust is via ***cargo*** and ***fn***. - -## Prerequisites - -First create an epty rust project as follows: - -```bash -cargo init --name func --bin -``` - -Make sure the project name is ***func*** and is of type ***bin***. Now just edit your code, once done you can create a function. - -## Creating a function - -Simply run - -```bash -fn init --runtime=rust / -``` - -This will create the ```func.yaml``` file required by functions, which can be built by running: - -```bash -fn build -``` - -## Testing - -```bash -fn run -``` diff --git a/examples/hello/rust/src/main.rs b/examples/hello/rust/src/main.rs deleted file mode 100644 index 020c757b1..000000000 --- a/examples/hello/rust/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -use std::io; -use std::io::Read; - -fn main() { - let mut buffer = String::new(); - let stdin = io::stdin(); - if stdin.lock().read_to_string(&mut buffer).is_ok() { - println!("Hello {}", buffer.trim()); - } -} diff --git a/examples/hotfunctions/http/func.go b/examples/hotfunctions/http/func.go deleted file mode 100644 index cba961f2e..000000000 --- a/examples/hotfunctions/http/func.go +++ /dev/null @@ -1,45 +0,0 @@ -package main - -import ( - "bufio" - "bytes" - "fmt" - "io/ioutil" - "net/http" - "os" - "strconv" -) - -func main() { - for { - res := http.Response{ - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - StatusCode: 200, - Status: "OK", - } - - r := bufio.NewReader(os.Stdin) - req, err := http.ReadRequest(r) - - var buf bytes.Buffer - if err != nil { - res.StatusCode = 500 - res.Status = http.StatusText(res.StatusCode) - fmt.Fprintln(&buf, err) - } else { - l, _ := strconv.Atoi(req.Header.Get("Content-Length")) - p := make([]byte, l) - r.Read(p) - fmt.Fprintf(&buf, "Hello %s\n", p) - for k, vs := range req.Header { - fmt.Fprintf(&buf, "ENV: %s %#v\n", k, vs) - } - } - - res.Body = ioutil.NopCloser(&buf) - res.ContentLength = int64(buf.Len()) - res.Write(os.Stdout) - } -} diff --git a/examples/hotfunctions/http/hotroute.json b/examples/hotfunctions/http/hotroute.json deleted file mode 100644 index af7e65172..000000000 --- a/examples/hotfunctions/http/hotroute.json +++ /dev/null @@ -1,9 +0,0 @@ -{"route":{ - "app_name": "myapp", - "path": "/hot", - "image": "USERNAME/hchttp", - "memory": 64, - "type": "sync", - "config": null, - "format": "http" -}} diff --git a/fn/init.go b/fn/init.go index 4e46293f8..dc9904786 100644 --- a/fn/init.go +++ b/fn/init.go @@ -17,8 +17,8 @@ import ( "strings" - "gitlab.oracledx.com/odx/functions/fn/langs" "github.com/urfave/cli" + "gitlab.oracledx.com/odx/functions/fn/langs" ) var ( @@ -157,9 +157,10 @@ func (a *initFnCmd) buildFuncFile(c *cli.Context) error { return err } a.runtime = rt - fmt.Printf("assuming %v runtime\n", rt) + fmt.Printf("Found %v, assuming %v runtime.\n", rt, rt) + } else { + fmt.Println("Runtime:", a.runtime) } - fmt.Println("runtime:", a.runtime) if _, ok := acceptableFnRuntimes[a.runtime]; !ok { return fmt.Errorf("init does not support the %s runtime, you'll have to create your own Dockerfile for this function", a.runtime) } @@ -180,7 +181,7 @@ func (a *initFnCmd) buildFuncFile(c *cli.Context) error { } } if a.entrypoint == "" && a.cmd == "" { - return fmt.Errorf("could not detect entrypoint or cmd for %v, use --entrypoint and/or --cmd to set them explicitly", a.runtime) + return fmt.Errorf("Could not detect entrypoint or cmd for %v, use --entrypoint and/or --cmd to set them explicitly", a.runtime) } return nil @@ -193,5 +194,5 @@ func detectRuntime(path string) (runtime string, err error) { return runtime, nil } } - return "", fmt.Errorf("no supported files found to guess runtime, please set runtime explicitly with --runtime flag") + return "", fmt.Errorf("No supported files found to guess runtime, please set runtime explicitly with --runtime flag") } From f97ac83255a70a80eec4aa6fb626253fd98abe88 Mon Sep 17 00:00:00 2001 From: Chad Arimura Date: Thu, 25 May 2017 14:31:22 -0700 Subject: [PATCH 05/17] more tutorial --- README.md | 4 +- examples/README.md | 2 +- examples/tutorial/hello/go/.gitignore | 7 +++ examples/tutorial/hello/go/README.md | 56 +++++++++++++++++++ examples/tutorial/hello/go/func.go | 20 +++++++ examples/tutorial/hello/go/hello.payload.json | 3 + examples/tutorial/hello/node/.gitignore | 3 + examples/tutorial/hello/node/README.md | 41 ++++++++++++++ examples/tutorial/hello/node/func.js | 9 +++ .../tutorial/hello/node/hello.payload.json | 3 + examples/tutorial/hello/node/package.json | 7 +++ examples/tutorial/hello/php/.gitignore | 1 + examples/tutorial/hello/php/Dockerfile | 6 ++ examples/tutorial/hello/php/README.md | 48 ++++++++++++++++ examples/tutorial/hello/php/composer.json | 4 ++ examples/tutorial/hello/php/func.yaml | 5 ++ .../tutorial/hello/php/hello.payload.json | 3 + examples/tutorial/hello/php/hello.php | 10 ++++ examples/tutorial/hello/python/.gitignore | 2 + examples/tutorial/hello/python/Dockerfile | 6 ++ examples/tutorial/hello/python/README.md | 48 ++++++++++++++++ .../tutorial/hello/python/hello.payload.json | 3 + examples/tutorial/hello/python/hello.py | 12 ++++ .../tutorial/hello/python/requirements.txt | 0 examples/tutorial/hello/ruby/.gitignore | 5 ++ examples/tutorial/hello/ruby/Gemfile | 4 ++ examples/tutorial/hello/ruby/README.md | 44 +++++++++++++++ examples/tutorial/hello/ruby/func.rb | 12 ++++ .../tutorial/hello/ruby/hello.payload.json | 3 + examples/tutorial/hello/rust/Cargo.toml | 6 ++ examples/tutorial/hello/rust/README.md | 33 +++++++++++ examples/tutorial/hello/rust/src/main.rs | 10 ++++ examples/tutorial/hotfunctions/http/func.go | 45 +++++++++++++++ .../tutorial/hotfunctions/http/hotroute.json | 9 +++ examples/tutorial/index.md | 7 +++ examples/tutorial/params/func.go | 30 ++++++++++ examples/tutorial/params/func.yaml | 6 ++ 37 files changed, 515 insertions(+), 2 deletions(-) create mode 100644 examples/tutorial/hello/go/.gitignore create mode 100644 examples/tutorial/hello/go/README.md create mode 100644 examples/tutorial/hello/go/func.go create mode 100644 examples/tutorial/hello/go/hello.payload.json create mode 100644 examples/tutorial/hello/node/.gitignore create mode 100644 examples/tutorial/hello/node/README.md create mode 100644 examples/tutorial/hello/node/func.js create mode 100644 examples/tutorial/hello/node/hello.payload.json create mode 100644 examples/tutorial/hello/node/package.json create mode 100644 examples/tutorial/hello/php/.gitignore create mode 100644 examples/tutorial/hello/php/Dockerfile create mode 100644 examples/tutorial/hello/php/README.md create mode 100644 examples/tutorial/hello/php/composer.json create mode 100644 examples/tutorial/hello/php/func.yaml create mode 100644 examples/tutorial/hello/php/hello.payload.json create mode 100644 examples/tutorial/hello/php/hello.php create mode 100644 examples/tutorial/hello/python/.gitignore create mode 100644 examples/tutorial/hello/python/Dockerfile create mode 100644 examples/tutorial/hello/python/README.md create mode 100644 examples/tutorial/hello/python/hello.payload.json create mode 100644 examples/tutorial/hello/python/hello.py create mode 100644 examples/tutorial/hello/python/requirements.txt create mode 100644 examples/tutorial/hello/ruby/.gitignore create mode 100644 examples/tutorial/hello/ruby/Gemfile create mode 100644 examples/tutorial/hello/ruby/README.md create mode 100644 examples/tutorial/hello/ruby/func.rb create mode 100644 examples/tutorial/hello/ruby/hello.payload.json create mode 100644 examples/tutorial/hello/rust/Cargo.toml create mode 100644 examples/tutorial/hello/rust/README.md create mode 100644 examples/tutorial/hello/rust/src/main.rs create mode 100644 examples/tutorial/hotfunctions/http/func.go create mode 100644 examples/tutorial/hotfunctions/http/hotroute.json create mode 100644 examples/tutorial/index.md create mode 100644 examples/tutorial/params/func.go create mode 100644 examples/tutorial/params/func.yaml diff --git a/README.md b/README.md index cb2338358..3db34dc05 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,9 @@ docker run --rm -it --link functions:api -p 4000:4000 -e "API_URL=http://api:808 For more information, see: [https://github.com/treeder/functions-ui](https://github.com/treeder/functions-ui) -## Next up: Walk through the following [tutorial series](docs/tutorial/) --> +# Next up +### Check out the [Tutorial Series](examples/tutorial/). + It will demonstrate some of Oracle Functions capabilities through a series of exmaples. We'll try to show examples in most major languages. This is a great place to start! diff --git a/examples/README.md b/examples/README.md index 135c2daf1..caa49f893 100644 --- a/examples/README.md +++ b/examples/README.md @@ -4,4 +4,4 @@ This directory has a collection of example functions you can look at to learn mo ## Tutorial Series -The [Tutorial Series](tutorial/) will demonstrate some of Oracle Functions capabilities through a series of exmaples. We'll try to examples in most major languages. This is a great place to start! +The [Tutorial Series](tutorial/) will demonstrate some of Oracle Functions capabilities through a series of exmaples. We'll try to show examples in most major languages. This is a great place to start! diff --git a/examples/tutorial/hello/go/.gitignore b/examples/tutorial/hello/go/.gitignore new file mode 100644 index 000000000..47868d339 --- /dev/null +++ b/examples/tutorial/hello/go/.gitignore @@ -0,0 +1,7 @@ +vendor/ +/hello +/go +/app +/__uberscript__ + +func.yaml diff --git a/examples/tutorial/hello/go/README.md b/examples/tutorial/hello/go/README.md new file mode 100644 index 000000000..1a27e91f9 --- /dev/null +++ b/examples/tutorial/hello/go/README.md @@ -0,0 +1,56 @@ +# Tutorial 1: Go Function w/ Input (3 minutes) + +This example will show you how to test and deploy Go (Golang) code to Oracle Functions. It will also demonstrate passing data in through stdin. + +First, run the following commands to create, run, and deploy your function: + +```sh +# Initialize your function creating a func.yaml file +fn init /hello + +# Test your function. This will run inside a container exactly how it will on the server +fn run + +# Now try with an input +cat hello.payload.json | fn run + +# Deploy your functions to the Oracle Functions server (default localhost:8080) +# This will create a route to your function as well +fn deploy myapp +``` +Now call your function: + +```sh +curl http://localhost:8080/r/myapp/hello +``` +Or call from a browser: [http://localhost:8080/r/myapp/hello](http://localhost:8080/r/myapp/hello) + +And now with the JSON input: + +```sh +curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/myapp/hello +``` + +That's it! + +# In Review + +1. We piped JSON data into the function at the command line +```sh +cat hello.payload.json | fn run +``` +2. We received our input through stdin +```go +json.NewDecoder(os.Stdin).Decode(p) +``` +3. We wrote our output to stdout +```go +fmt.Printf("Hello") +``` +4. We sent stderr to the server logs +```go +log.Println("here") +``` + +# Next Up +## [Tutorial 2: Input Parameters](examples/tutorial/params) \ No newline at end of file diff --git a/examples/tutorial/hello/go/func.go b/examples/tutorial/hello/go/func.go new file mode 100644 index 000000000..74ec37c55 --- /dev/null +++ b/examples/tutorial/hello/go/func.go @@ -0,0 +1,20 @@ +package main + +import ( + "encoding/json" + "fmt" + "log" + "os" +) + +type Person struct { + Name string +} + +func main() { + p := &Person{Name: "World"} + json.NewDecoder(os.Stdin).Decode(p) + fmt.Printf("Hello %v!\n", p.Name) + + log.Println("---> stderr goes to the server logs.") +} diff --git a/examples/tutorial/hello/go/hello.payload.json b/examples/tutorial/hello/go/hello.payload.json new file mode 100644 index 000000000..97e136b69 --- /dev/null +++ b/examples/tutorial/hello/go/hello.payload.json @@ -0,0 +1,3 @@ +{ + "name": "Johnny" +} diff --git a/examples/tutorial/hello/node/.gitignore b/examples/tutorial/hello/node/.gitignore new file mode 100644 index 000000000..8977e475d --- /dev/null +++ b/examples/tutorial/hello/node/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +func.yaml +Dockerfile diff --git a/examples/tutorial/hello/node/README.md b/examples/tutorial/hello/node/README.md new file mode 100644 index 000000000..2a4baff97 --- /dev/null +++ b/examples/tutorial/hello/node/README.md @@ -0,0 +1,41 @@ +## Quick Example for a NodeJS Function (4 minutes) + +This example will show you how to test and deploy a Node function to Oracle Functions. + +```sh +# create your func.yaml file +fn init /hello +# build the function +fn build +# test it +cat hello.payload.json | fn run +# push it to Docker Hub +fn push +# Create a route to this function on Oracle Functions +fn routes create myapp /hello +``` + +Now surf to: http://localhost:8080/r/myapp/hello + +## Dependencies + +Create a [package.json](https://docs.npmjs.com/getting-started/using-a-package.json) file in your functions directory. + +Run: + +```sh +docker run --rm -v "$PWD":/function -w /function funcy/node:dev npm install +``` + +Then everything should work. + +For example, using the `package.json` file in this directory which includes the [request](https://www.npmjs.com/package/request) package, you can add this to func.js and it will work: + +```js +var request = require('request'); +request('http://www.google.com', function (error, response, body) { + if (!error && response.statusCode == 200) { + console.log(body) // Show the HTML for the Google homepage. + } +}) +``` diff --git a/examples/tutorial/hello/node/func.js b/examples/tutorial/hello/node/func.js new file mode 100644 index 000000000..356544e81 --- /dev/null +++ b/examples/tutorial/hello/node/func.js @@ -0,0 +1,9 @@ +name = "World"; +fs = require('fs'); +try { + obj = JSON.parse(fs.readFileSync('/dev/stdin').toString()) + if (obj.name != "") { + name = obj.name + } +} catch(e) {} +console.log("Hello", name, "from Node!"); diff --git a/examples/tutorial/hello/node/hello.payload.json b/examples/tutorial/hello/node/hello.payload.json new file mode 100644 index 000000000..97e136b69 --- /dev/null +++ b/examples/tutorial/hello/node/hello.payload.json @@ -0,0 +1,3 @@ +{ + "name": "Johnny" +} diff --git a/examples/tutorial/hello/node/package.json b/examples/tutorial/hello/node/package.json new file mode 100644 index 000000000..f332baddb --- /dev/null +++ b/examples/tutorial/hello/node/package.json @@ -0,0 +1,7 @@ +{ + "name": "my-awesome-func", + "version": "1.0.0", + "dependencies": { + "request": "^2.78.0" + } +} \ No newline at end of file diff --git a/examples/tutorial/hello/php/.gitignore b/examples/tutorial/hello/php/.gitignore new file mode 100644 index 000000000..48b8bf907 --- /dev/null +++ b/examples/tutorial/hello/php/.gitignore @@ -0,0 +1 @@ +vendor/ diff --git a/examples/tutorial/hello/php/Dockerfile b/examples/tutorial/hello/php/Dockerfile new file mode 100644 index 000000000..1da497e06 --- /dev/null +++ b/examples/tutorial/hello/php/Dockerfile @@ -0,0 +1,6 @@ +FROM funcy/php + +WORKDIR /app +ADD . /app + +ENTRYPOINT ["php", "hello.php"] diff --git a/examples/tutorial/hello/php/README.md b/examples/tutorial/hello/php/README.md new file mode 100644 index 000000000..1ccc9b1d1 --- /dev/null +++ b/examples/tutorial/hello/php/README.md @@ -0,0 +1,48 @@ +## Quick Example for a PHP Function (4 minutes) + +This example will show you how to test and deploy Go (Golang) code to Oracle Functions. + +### 1. Prepare the `func.yaml` file: + +At func.yaml you will find: + +```yml +name: USERNAME/hello +version: 0.0.1 +path: /hello +build: +- docker run --rm -v "$PWD":/worker -w /worker funcy/php:dev composer install +``` + +The important step here is to ensure you replace `USERNAME` with your Docker Hub account name. Some points of note: +the application name is `phpapp` and the route for incoming requests is `/hello`. These informations are relevant for +the moment you try to test this function. + +### 2. Build: + +```sh +# build the function +fn build +# test it +cat hello.payload.json | fn run +# push it to Docker Hub +fn push +# Create a route to this function on Oracle Functions +fn routes create phpapp /hello +``` + +`-v` is optional, but it allows you to see how this function is being built. + +### 3. Queue jobs for your function + +Now you can start jobs on your function. Let's quickly queue up a job to try it out. + +```sh +cat hello.payload.json | fn call phpapp /hello +``` + +Here's a curl example to show how easy it is to do in any language: + +```sh +curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/phpapp/hello +``` \ No newline at end of file diff --git a/examples/tutorial/hello/php/composer.json b/examples/tutorial/hello/php/composer.json new file mode 100644 index 000000000..df8dd9cf8 --- /dev/null +++ b/examples/tutorial/hello/php/composer.json @@ -0,0 +1,4 @@ +{ + "require": { + } +} diff --git a/examples/tutorial/hello/php/func.yaml b/examples/tutorial/hello/php/func.yaml new file mode 100644 index 000000000..027b012ee --- /dev/null +++ b/examples/tutorial/hello/php/func.yaml @@ -0,0 +1,5 @@ +name: USERNAME/hello +version: 0.0.1 +path: /hello +build: +- docker run --rm -v "$PWD":/worker -w /worker funcy/php:dev composer install diff --git a/examples/tutorial/hello/php/hello.payload.json b/examples/tutorial/hello/php/hello.payload.json new file mode 100644 index 000000000..97e136b69 --- /dev/null +++ b/examples/tutorial/hello/php/hello.payload.json @@ -0,0 +1,3 @@ +{ + "name": "Johnny" +} diff --git a/examples/tutorial/hello/php/hello.php b/examples/tutorial/hello/php/hello.php new file mode 100644 index 000000000..7828f1f95 --- /dev/null +++ b/examples/tutorial/hello/php/hello.php @@ -0,0 +1,10 @@ + 0.14.0' +gem 'json', '> 1.8.2' diff --git a/examples/tutorial/hello/ruby/README.md b/examples/tutorial/hello/ruby/README.md new file mode 100644 index 000000000..05ef81eea --- /dev/null +++ b/examples/tutorial/hello/ruby/README.md @@ -0,0 +1,44 @@ +## Quick Example for a Ruby Function (4 minutes) + +This example will show you how to test and deploy a Ruby function to Oracle Functions. + +```sh +# create your func.yaml file +fn init /hello +# install dependencies, we need the json gem to run this +docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle install --standalone --clean +# build the function +fn build +# test it +cat hello.payload.json | fn run +# push it to Docker Hub +fn push +# Create a route to this function on Oracle Functions +fn routes create myapp /hello +``` + +Now surf to: http://localhost:8080/r/myapp/hello + +## Dependencies + +Create a [Gemfile](http://bundler.io/gemfile.html) file in your function directory, then run: + +```sh +docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle install --standalone --clean +``` + +Ruby doesn't pick up the gems automatically, so you'll have to add this to the top of your `func.rb` file: + +```ruby +require_relative 'bundle/bundler/setup' +``` + +Open `func.rb` to see it in action. + +To update dependencies: + +```sh +docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle update +# then install again to vendor them +docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle update +``` diff --git a/examples/tutorial/hello/ruby/func.rb b/examples/tutorial/hello/ruby/func.rb new file mode 100644 index 000000000..a16a04030 --- /dev/null +++ b/examples/tutorial/hello/ruby/func.rb @@ -0,0 +1,12 @@ +require_relative 'bundle/bundler/setup' +require 'json' + +name = "World" + +payload = STDIN.read +if payload != "" + payload = JSON.parse(payload) + name = payload['name'] +end + +puts "Hello #{name} from Ruby!" diff --git a/examples/tutorial/hello/ruby/hello.payload.json b/examples/tutorial/hello/ruby/hello.payload.json new file mode 100644 index 000000000..97e136b69 --- /dev/null +++ b/examples/tutorial/hello/ruby/hello.payload.json @@ -0,0 +1,3 @@ +{ + "name": "Johnny" +} diff --git a/examples/tutorial/hello/rust/Cargo.toml b/examples/tutorial/hello/rust/Cargo.toml new file mode 100644 index 000000000..7c3608e1d --- /dev/null +++ b/examples/tutorial/hello/rust/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "func" +version = "0.1.0" +authors = ["Seif Lotfy "] + +[dependencies] diff --git a/examples/tutorial/hello/rust/README.md b/examples/tutorial/hello/rust/README.md new file mode 100644 index 000000000..895f3ba51 --- /dev/null +++ b/examples/tutorial/hello/rust/README.md @@ -0,0 +1,33 @@ +# Using rust with functions + +The easiest way to create a function in rust is via ***cargo*** and ***fn***. + +## Prerequisites + +First create an epty rust project as follows: + +```bash +cargo init --name func --bin +``` + +Make sure the project name is ***func*** and is of type ***bin***. Now just edit your code, once done you can create a function. + +## Creating a function + +Simply run + +```bash +fn init --runtime=rust / +``` + +This will create the ```func.yaml``` file required by functions, which can be built by running: + +```bash +fn build +``` + +## Testing + +```bash +fn run +``` diff --git a/examples/tutorial/hello/rust/src/main.rs b/examples/tutorial/hello/rust/src/main.rs new file mode 100644 index 000000000..020c757b1 --- /dev/null +++ b/examples/tutorial/hello/rust/src/main.rs @@ -0,0 +1,10 @@ +use std::io; +use std::io::Read; + +fn main() { + let mut buffer = String::new(); + let stdin = io::stdin(); + if stdin.lock().read_to_string(&mut buffer).is_ok() { + println!("Hello {}", buffer.trim()); + } +} diff --git a/examples/tutorial/hotfunctions/http/func.go b/examples/tutorial/hotfunctions/http/func.go new file mode 100644 index 000000000..cba961f2e --- /dev/null +++ b/examples/tutorial/hotfunctions/http/func.go @@ -0,0 +1,45 @@ +package main + +import ( + "bufio" + "bytes" + "fmt" + "io/ioutil" + "net/http" + "os" + "strconv" +) + +func main() { + for { + res := http.Response{ + Proto: "HTTP/1.1", + ProtoMajor: 1, + ProtoMinor: 1, + StatusCode: 200, + Status: "OK", + } + + r := bufio.NewReader(os.Stdin) + req, err := http.ReadRequest(r) + + var buf bytes.Buffer + if err != nil { + res.StatusCode = 500 + res.Status = http.StatusText(res.StatusCode) + fmt.Fprintln(&buf, err) + } else { + l, _ := strconv.Atoi(req.Header.Get("Content-Length")) + p := make([]byte, l) + r.Read(p) + fmt.Fprintf(&buf, "Hello %s\n", p) + for k, vs := range req.Header { + fmt.Fprintf(&buf, "ENV: %s %#v\n", k, vs) + } + } + + res.Body = ioutil.NopCloser(&buf) + res.ContentLength = int64(buf.Len()) + res.Write(os.Stdout) + } +} diff --git a/examples/tutorial/hotfunctions/http/hotroute.json b/examples/tutorial/hotfunctions/http/hotroute.json new file mode 100644 index 000000000..af7e65172 --- /dev/null +++ b/examples/tutorial/hotfunctions/http/hotroute.json @@ -0,0 +1,9 @@ +{"route":{ + "app_name": "myapp", + "path": "/hot", + "image": "USERNAME/hchttp", + "memory": 64, + "type": "sync", + "config": null, + "format": "http" +}} diff --git a/examples/tutorial/index.md b/examples/tutorial/index.md new file mode 100644 index 000000000..530d72ddc --- /dev/null +++ b/examples/tutorial/index.md @@ -0,0 +1,7 @@ + +# Tutorial Series + +1. [Tutorial 1](examples/tutorial/hello): Learn the basics about sending data into your function +2. [Tutorial 2](examples/tutorial/params): Learn how to get parameters from a web request +3. [Tutorial 3](examples/tutorial/hotfunctions): Write your first HotFunction (stays alive to minimze latency between requests) +4. [Tutorial 4](): TBD \ No newline at end of file diff --git a/examples/tutorial/params/func.go b/examples/tutorial/params/func.go new file mode 100644 index 000000000..38b34dc59 --- /dev/null +++ b/examples/tutorial/params/func.go @@ -0,0 +1,30 @@ +package main + +import ( + "fmt" + "log" + "net/url" + "os" +) + +func main() { + s := os.Getenv("REQUEST_URL") + + fmt.Printf("REQUEST_URL --> %v\n\n", s) + + u, err := url.Parse(s) + if err != nil { + log.Fatal(err) + } + + m, _ := url.ParseQuery(u.RawQuery) + + if len(m) == 0 { + fmt.Println("Try adding some URL params like &id=123") + } else { + for k, v := range m { + fmt.Printf("found param: %v, val: %v\n", k, v[0]) + } + } + +} diff --git a/examples/tutorial/params/func.yaml b/examples/tutorial/params/func.yaml new file mode 100644 index 000000000..f26e7a126 --- /dev/null +++ b/examples/tutorial/params/func.yaml @@ -0,0 +1,6 @@ +name: carimura2/fn3_request +version: 0.0.6 +runtime: go +entrypoint: ./func +path: /fn3 +max_concurrency: 1 From 2ed750426926aa0152355449d4325e0f1bcdf06b Mon Sep 17 00:00:00 2001 From: Chad Arimura Date: Thu, 25 May 2017 14:35:02 -0700 Subject: [PATCH 06/17] tutorial readme --- README.md | 4 ++-- examples/tutorial/{index.md => README.md} | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) rename examples/tutorial/{index.md => README.md} (61%) diff --git a/README.md b/README.md index 3db34dc05..e2c238c73 100644 --- a/README.md +++ b/README.md @@ -117,9 +117,9 @@ you can update your code and run ```fn deploy myapp``` again. ## To Learn More -- Walk through the following [tutorial series](docs/tutorial) +- Visit our Functions [Tutorial Series](examples/tutorial/) - See our [full documentation](docs/README.md) -- View our [examples directory](/examples) +- View all of our [examples](/examples) - You can also write your functions in AWS [Lambda format](docs/lambda/README.md) ## Get Involved diff --git a/examples/tutorial/index.md b/examples/tutorial/README.md similarity index 61% rename from examples/tutorial/index.md rename to examples/tutorial/README.md index 530d72ddc..1df9b7924 100644 --- a/examples/tutorial/index.md +++ b/examples/tutorial/README.md @@ -1,6 +1,9 @@ # Tutorial Series +Welcome to the Oracle Functions Tutorial Series, the best way to get started with Oracle Functions and serverless computing. In the following +tutorials, we'll gradually introduce many of the key features of Oracle Functions. + 1. [Tutorial 1](examples/tutorial/hello): Learn the basics about sending data into your function 2. [Tutorial 2](examples/tutorial/params): Learn how to get parameters from a web request 3. [Tutorial 3](examples/tutorial/hotfunctions): Write your first HotFunction (stays alive to minimze latency between requests) From da09f187419ace47452e72365972df55c1f8a89f Mon Sep 17 00:00:00 2001 From: Chad Arimura Date: Thu, 25 May 2017 14:42:33 -0700 Subject: [PATCH 07/17] readme mods --- examples/tutorial/README.md | 13 +++++++++---- examples/tutorial/hello/go/README.md | 17 ++++++++++++----- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/examples/tutorial/README.md b/examples/tutorial/README.md index 1df9b7924..ab947e8ae 100644 --- a/examples/tutorial/README.md +++ b/examples/tutorial/README.md @@ -4,7 +4,12 @@ Welcome to the Oracle Functions Tutorial Series, the best way to get started with Oracle Functions and serverless computing. In the following tutorials, we'll gradually introduce many of the key features of Oracle Functions. -1. [Tutorial 1](examples/tutorial/hello): Learn the basics about sending data into your function -2. [Tutorial 2](examples/tutorial/params): Learn how to get parameters from a web request -3. [Tutorial 3](examples/tutorial/hotfunctions): Write your first HotFunction (stays alive to minimze latency between requests) -4. [Tutorial 4](): TBD \ No newline at end of file + +**[Tutorial 1](examples/tutorial/hello)** +: Learn the basics about sending data into your function + +**[Tutorial 2](examples/tutorial/params)**: Learn how to get parameters from a web request + +**[Tutorial 3](examples/tutorial/hotfunctions)**: Write your first HotFunction (stays alive to minimize latency between requests) + +**[Tutorial 4]()**: TBD diff --git a/examples/tutorial/hello/go/README.md b/examples/tutorial/hello/go/README.md index 1a27e91f9..5e2f7cbe0 100644 --- a/examples/tutorial/hello/go/README.md +++ b/examples/tutorial/hello/go/README.md @@ -2,7 +2,7 @@ This example will show you how to test and deploy Go (Golang) code to Oracle Functions. It will also demonstrate passing data in through stdin. -First, run the following commands to create, run, and deploy your function: +### First, run the following commands to create, run, and deploy your function: ```sh # Initialize your function creating a func.yaml file @@ -18,36 +18,43 @@ cat hello.payload.json | fn run # This will create a route to your function as well fn deploy myapp ``` -Now call your function: +### Now call your function: ```sh curl http://localhost:8080/r/myapp/hello ``` -Or call from a browser: [http://localhost:8080/r/myapp/hello](http://localhost:8080/r/myapp/hello) +### Or call from a browser: [http://localhost:8080/r/myapp/hello](http://localhost:8080/r/myapp/hello) -And now with the JSON input: +### And now with the JSON input: ```sh curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/myapp/hello ``` -That's it! +### That's it! # In Review 1. We piped JSON data into the function at the command line + ```sh cat hello.payload.json | fn run ``` + 2. We received our input through stdin + ```go json.NewDecoder(os.Stdin).Decode(p) ``` + 3. We wrote our output to stdout + ```go fmt.Printf("Hello") ``` + 4. We sent stderr to the server logs + ```go log.Println("here") ``` From 2c899e39059b55e83747e033f2f701c1ef344190 Mon Sep 17 00:00:00 2001 From: Chad Arimura Date: Thu, 25 May 2017 14:44:02 -0700 Subject: [PATCH 08/17] readme mods --- examples/tutorial/hello/go/README.md | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/examples/tutorial/hello/go/README.md b/examples/tutorial/hello/go/README.md index 5e2f7cbe0..3ac866716 100644 --- a/examples/tutorial/hello/go/README.md +++ b/examples/tutorial/hello/go/README.md @@ -35,17 +35,9 @@ curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://l # In Review -1. We piped JSON data into the function at the command line +1. We piped JSON data into the function at the command line: `cat hello.payload.json | fn run` -```sh -cat hello.payload.json | fn run -``` - -2. We received our input through stdin - -```go -json.NewDecoder(os.Stdin).Decode(p) -``` +2. We received our input through stdin: `json.NewDecoder(os.Stdin).Decode(p)` 3. We wrote our output to stdout From 12d44fab6a7d63749e97e2fc1e3e91575cc9e3ac Mon Sep 17 00:00:00 2001 From: Chad Arimura Date: Thu, 25 May 2017 14:51:10 -0700 Subject: [PATCH 09/17] readme mods --- examples/tutorial/hello/go/README.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/examples/tutorial/hello/go/README.md b/examples/tutorial/hello/go/README.md index 3ac866716..93b73d390 100644 --- a/examples/tutorial/hello/go/README.md +++ b/examples/tutorial/hello/go/README.md @@ -35,21 +35,25 @@ curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://l # In Review -1. We piped JSON data into the function at the command line: `cat hello.payload.json | fn run` +1. We piped JSON data into the function at the command line + ```sh + cat hello.payload.json | fn run + ``` -2. We received our input through stdin: `json.NewDecoder(os.Stdin).Decode(p)` +2. We received our input through stdin + ```go + json.NewDecoder(os.Stdin).Decode(p) + ``` 3. We wrote our output to stdout - -```go -fmt.Printf("Hello") -``` + ```go + fmt.Printf("Hello") + ``` 4. We sent stderr to the server logs - -```go -log.Println("here") -``` + ```go + log.Println("here") + ``` # Next Up ## [Tutorial 2: Input Parameters](examples/tutorial/params) \ No newline at end of file From bf642a0a83bf3c722611432cff643f60713331fc Mon Sep 17 00:00:00 2001 From: Chad Arimura Date: Thu, 25 May 2017 14:52:13 -0700 Subject: [PATCH 10/17] readme mods --- examples/tutorial/hello/go/README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/tutorial/hello/go/README.md b/examples/tutorial/hello/go/README.md index 93b73d390..6911c158f 100644 --- a/examples/tutorial/hello/go/README.md +++ b/examples/tutorial/hello/go/README.md @@ -2,7 +2,7 @@ This example will show you how to test and deploy Go (Golang) code to Oracle Functions. It will also demonstrate passing data in through stdin. -### First, run the following commands to create, run, and deploy your function: +### First, run the following commands: ```sh # Initialize your function creating a func.yaml file @@ -23,15 +23,16 @@ fn deploy myapp ```sh curl http://localhost:8080/r/myapp/hello ``` -### Or call from a browser: [http://localhost:8080/r/myapp/hello](http://localhost:8080/r/myapp/hello) -### And now with the JSON input: +Or call from a browser: [http://localhost:8080/r/myapp/hello](http://localhost:8080/r/myapp/hello) + +And now with the JSON input: ```sh curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/myapp/hello ``` -### That's it! +That's it! # In Review From c52039eb35a796aa8cf087bdc0202db9d8658a01 Mon Sep 17 00:00:00 2001 From: Chad Arimura Date: Thu, 25 May 2017 14:54:11 -0700 Subject: [PATCH 11/17] readme mods --- examples/tutorial/hello/go/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/tutorial/hello/go/README.md b/examples/tutorial/hello/go/README.md index 6911c158f..1f2893150 100644 --- a/examples/tutorial/hello/go/README.md +++ b/examples/tutorial/hello/go/README.md @@ -41,17 +41,17 @@ That's it! cat hello.payload.json | fn run ``` -2. We received our input through stdin +2. We received our function input through **stdin** ```go json.NewDecoder(os.Stdin).Decode(p) ``` -3. We wrote our output to stdout +3. We wrote our output to **stdout** ```go fmt.Printf("Hello") ``` -4. We sent stderr to the server logs +4. We sent **stderr** to the server logs ```go log.Println("here") ``` From 82f608558b7d792bb82cd1107c705fa5b1b24ac4 Mon Sep 17 00:00:00 2001 From: Chad Arimura Date: Thu, 25 May 2017 15:38:39 -0700 Subject: [PATCH 12/17] update ruby helloworld --- examples/tutorial/hello/go/README.md | 5 ++ examples/tutorial/hello/ruby/README.md | 90 ++++++++++++++++++++------ examples/tutorial/hello/ruby/func.rb | 4 +- 3 files changed, 79 insertions(+), 20 deletions(-) diff --git a/examples/tutorial/hello/go/README.md b/examples/tutorial/hello/go/README.md index 1f2893150..1a87a0343 100644 --- a/examples/tutorial/hello/go/README.md +++ b/examples/tutorial/hello/go/README.md @@ -34,6 +34,10 @@ curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://l That's it! +### Note on Dependencies + +In Go, simply put them all in the `vendor/` directory. + # In Review 1. We piped JSON data into the function at the command line @@ -56,5 +60,6 @@ That's it! log.Println("here") ``` + # Next Up ## [Tutorial 2: Input Parameters](examples/tutorial/params) \ No newline at end of file diff --git a/examples/tutorial/hello/ruby/README.md b/examples/tutorial/hello/ruby/README.md index 05ef81eea..5f2ca5253 100644 --- a/examples/tutorial/hello/ruby/README.md +++ b/examples/tutorial/hello/ruby/README.md @@ -1,27 +1,43 @@ -## Quick Example for a Ruby Function (4 minutes) +# Tutorial 1: Ruby Function w/ Input (3 minutes) -This example will show you how to test and deploy a Ruby function to Oracle Functions. +This example will show you how to test and deploy Ruby code to Oracle Functions. It will also demonstrate passing data in through stdin. + +### First, run the following commands: ```sh -# create your func.yaml file -fn init /hello -# install dependencies, we need the json gem to run this -docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle install --standalone --clean -# build the function -fn build -# test it +# Initialize your function creating a func.yaml file +fn init /hello + +# Test your function. +# This will run inside a container exactly how it will on the server. It will also install and vendor dependencies from Gemfile +fn run + +# Now try with an input cat hello.payload.json | fn run -# push it to Docker Hub -fn push -# Create a route to this function on Oracle Functions -fn routes create myapp /hello + +# Deploy your functions to the Oracle Functions server (default localhost:8080) +# This will create a route to your function as well +fn deploy myapp +``` +### Now call your function: + +```sh +curl http://localhost:8080/r/myapp/hello ``` -Now surf to: http://localhost:8080/r/myapp/hello +Or call from a browser: [http://localhost:8080/r/myapp/hello](http://localhost:8080/r/myapp/hello) -## Dependencies +And now with the JSON input: -Create a [Gemfile](http://bundler.io/gemfile.html) file in your function directory, then run: +```sh +curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/myapp/hello +``` + +That's it! + +### Note on Dependencies + +In Ruby, we create a [Gemfile](http://bundler.io/gemfile.html) file in your function directory, then run: ```sh docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle install --standalone --clean @@ -38,7 +54,43 @@ Open `func.rb` to see it in action. To update dependencies: ```sh -docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle update -# then install again to vendor them -docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle update +# Let's run bundle update +docker run --rm -it -v ${PWD}:/worker -w /worker funcy/ruby:dev bundle update + +# Then bundle install again to vendor them +docker run --rm -it -v ${PWD}:/worker -w /worker funcy/ruby:dev bundle install --standalone --clean ``` + +# In Review + +1. We piped JSON data into the function at the command line + ```sh + cat hello.payload.json | fn run + ``` + +2. We received our function input through **stdin** + ```ruby + payload = STDIN.read + ``` + +3. We wrote our output to **stdout** + ```ruby + puts "Hello #{name} from Ruby!" + ``` + +4. We sent **stderr** to the server logs + ```ruby + STDERR.puts + ``` + +5. We enabled our Ruby gem dependencies using `require_relative` + ```ruby + require_relative 'bundle/bundler/setup' + ``` + + +# Next Up +## [Tutorial 2: Input Parameters](examples/tutorial/params) + + + diff --git a/examples/tutorial/hello/ruby/func.rb b/examples/tutorial/hello/ruby/func.rb index a16a04030..6399af036 100644 --- a/examples/tutorial/hello/ruby/func.rb +++ b/examples/tutorial/hello/ruby/func.rb @@ -9,4 +9,6 @@ if payload != "" name = payload['name'] end -puts "Hello #{name} from Ruby!" +puts "Hello #{name}!" + +STDERR.puts "---> STDERR goes to server logs" From 98e05eec6345f74fc067e571338e88b9e034c492 Mon Sep 17 00:00:00 2001 From: Chad Arimura Date: Fri, 26 May 2017 10:32:07 -0700 Subject: [PATCH 13/17] init cli changes, removed app create from initial walkthrough --- README.md | 3 --- fn/init.go | 12 ++++++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e2c238c73..761547de3 100644 --- a/README.md +++ b/README.md @@ -88,9 +88,6 @@ func main() { Now run the following CLI commands: ```sh -# Create your first application -fn apps create myapp - # Initialize your function # This detects your runtime from the code above and creates a func.yaml fn init /hello diff --git a/fn/init.go b/fn/init.go index dc9904786..f07d7bb0a 100644 --- a/fn/init.go +++ b/fn/init.go @@ -99,7 +99,7 @@ func (a *initFnCmd) init(c *cli.Context) error { return err } if ff != nil { - return errors.New("function file already exists") + return errors.New("Function file already exists") } } @@ -130,7 +130,7 @@ func (a *initFnCmd) init(c *cli.Context) error { return err } - fmt.Println("func.yaml created.") + fmt.Println("func.yaml created") return nil } @@ -142,11 +142,11 @@ func (a *initFnCmd) buildFuncFile(c *cli.Context) error { a.name = c.Args().First() if a.name == "" || strings.Contains(a.name, ":") { - return errors.New("Please specify a name for your function in the following format /.\nTry: fn init /") + return errors.New("please specify a name for your function in the following format /.\nTry: fn init /") } if exists("Dockerfile") { - fmt.Println("Dockerfile found, will use that to build.") + fmt.Println("Dockerfile found. Let's use that to build...") return nil } @@ -181,7 +181,7 @@ func (a *initFnCmd) buildFuncFile(c *cli.Context) error { } } if a.entrypoint == "" && a.cmd == "" { - return fmt.Errorf("Could not detect entrypoint or cmd for %v, use --entrypoint and/or --cmd to set them explicitly", a.runtime) + return fmt.Errorf("could not detect entrypoint or cmd for %v, use --entrypoint and/or --cmd to set them explicitly", a.runtime) } return nil @@ -194,5 +194,5 @@ func detectRuntime(path string) (runtime string, err error) { return runtime, nil } } - return "", fmt.Errorf("No supported files found to guess runtime, please set runtime explicitly with --runtime flag") + return "", fmt.Errorf("no supported files found to guess runtime, please set runtime explicitly with --runtime flag.") } From b49337d4e0a4bf4072b814f83d1cd984ae37b35c Mon Sep 17 00:00:00 2001 From: Chad Arimura Date: Fri, 26 May 2017 12:36:38 -0700 Subject: [PATCH 14/17] php langhelper (needs funcy/php), tutorial --- examples/tutorial/hello/node/README.md | 74 +++++++++++++--- examples/tutorial/hello/node/func.js | 2 + examples/tutorial/hello/php/Dockerfile | 6 -- examples/tutorial/hello/php/README.md | 88 +++++++++++++------ .../hello/php/{hello.php => func.php} | 0 examples/tutorial/hello/php/func.yaml | 7 +- fn/init.go | 15 ++-- fn/langs/base.go | 2 + fn/langs/php.go | 49 +++++++++++ fn/main.go | 2 +- 10 files changed, 188 insertions(+), 57 deletions(-) delete mode 100644 examples/tutorial/hello/php/Dockerfile rename examples/tutorial/hello/php/{hello.php => func.php} (100%) create mode 100644 fn/langs/php.go diff --git a/examples/tutorial/hello/node/README.md b/examples/tutorial/hello/node/README.md index 2a4baff97..83903eb00 100644 --- a/examples/tutorial/hello/node/README.md +++ b/examples/tutorial/hello/node/README.md @@ -1,23 +1,41 @@ -## Quick Example for a NodeJS Function (4 minutes) +# Tutorial 1: NodeJS Function w/ Input (3 minutes) -This example will show you how to test and deploy a Node function to Oracle Functions. +This example will show you how to test and deploy Node code to Oracle Functions. It will also demonstrate passing data in through stdin. + +### First, run the following commands: ```sh -# create your func.yaml file -fn init /hello -# build the function -fn build -# test it +# Initialize your function creating a func.yaml file +fn init /hello + +# Test your function. +# This will run inside a container exactly how it will on the server. It will also install and vendor dependencies from Gemfile +fn run + +# Now try with an input cat hello.payload.json | fn run -# push it to Docker Hub -fn push -# Create a route to this function on Oracle Functions -fn routes create myapp /hello + +# Deploy your functions to the Oracle Functions server (default localhost:8080) +# This will create a route to your function as well +fn deploy myapp +``` +### Now call your function: + +```sh +curl http://localhost:8080/r/myapp/hello ``` -Now surf to: http://localhost:8080/r/myapp/hello +Or call from a browser: [http://localhost:8080/r/myapp/hello](http://localhost:8080/r/myapp/hello) -## Dependencies +And now with the JSON input: + +```sh +curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/myapp/hello +``` + +That's it! + +### Note on Dependencies Create a [package.json](https://docs.npmjs.com/getting-started/using-a-package.json) file in your functions directory. @@ -39,3 +57,33 @@ request('http://www.google.com', function (error, response, body) { } }) ``` + + +# In Review + +1. We piped JSON data into the function at the command line + ```sh + cat hello.payload.json | fn run + ``` + +2. We received our function input through **stdin** + ```node + obj = JSON.parse(fs.readFileSync('/dev/stdin').toString()) + ``` + +3. We wrote our output to **stdout** + ```node + console.log + ``` + +4. We sent **stderr** to the server logs + ```node + console.error + ``` + + +# Next Up +## [Tutorial 2: Input Parameters](examples/tutorial/params) + + + diff --git a/examples/tutorial/hello/node/func.js b/examples/tutorial/hello/node/func.js index 356544e81..5d78d1143 100644 --- a/examples/tutorial/hello/node/func.js +++ b/examples/tutorial/hello/node/func.js @@ -7,3 +7,5 @@ try { } } catch(e) {} console.log("Hello", name, "from Node!"); + +console.error("Stderr goes to the server logs..."); diff --git a/examples/tutorial/hello/php/Dockerfile b/examples/tutorial/hello/php/Dockerfile deleted file mode 100644 index 1da497e06..000000000 --- a/examples/tutorial/hello/php/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM funcy/php - -WORKDIR /app -ADD . /app - -ENTRYPOINT ["php", "hello.php"] diff --git a/examples/tutorial/hello/php/README.md b/examples/tutorial/hello/php/README.md index 1ccc9b1d1..d00232b40 100644 --- a/examples/tutorial/hello/php/README.md +++ b/examples/tutorial/hello/php/README.md @@ -1,10 +1,41 @@ -## Quick Example for a PHP Function (4 minutes) +# Tutorial 1: PHP Function w/ Input (3 minutes) -This example will show you how to test and deploy Go (Golang) code to Oracle Functions. +This example will show you how to test and deploy PHP code to Oracle Functions. It will also demonstrate passing data in through stdin. -### 1. Prepare the `func.yaml` file: +### First, run the following commands: -At func.yaml you will find: +```sh +# Initialize your function creating a func.yaml file +fn init /hello + +# Test your function. +# This will run inside a container exactly how it will on the server. It will also install and vendor dependencies from Gemfile +fn run + +# Now try with an input +cat hello.payload.json | fn run + +# Deploy your functions to the Oracle Functions server (default localhost:8080) +# This will create a route to your function as well +fn deploy myapp +``` +### Now call your function: + +```sh +curl http://localhost:8080/r/myapp/hello +``` + +Or call from a browser: [http://localhost:8080/r/myapp/hello](http://localhost:8080/r/myapp/hello) + +And now with the JSON input: + +```sh +curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/myapp/hello +``` + +That's it! + +### Note on Dependencies ```yml name: USERNAME/hello @@ -14,25 +45,6 @@ build: - docker run --rm -v "$PWD":/worker -w /worker funcy/php:dev composer install ``` -The important step here is to ensure you replace `USERNAME` with your Docker Hub account name. Some points of note: -the application name is `phpapp` and the route for incoming requests is `/hello`. These informations are relevant for -the moment you try to test this function. - -### 2. Build: - -```sh -# build the function -fn build -# test it -cat hello.payload.json | fn run -# push it to Docker Hub -fn push -# Create a route to this function on Oracle Functions -fn routes create phpapp /hello -``` - -`-v` is optional, but it allows you to see how this function is being built. - ### 3. Queue jobs for your function Now you can start jobs on your function. Let's quickly queue up a job to try it out. @@ -41,8 +53,30 @@ Now you can start jobs on your function. Let's quickly queue up a job to try it cat hello.payload.json | fn call phpapp /hello ``` -Here's a curl example to show how easy it is to do in any language: -```sh -curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/phpapp/hello -``` \ No newline at end of file + +# In Review + +1. We piped JSON data into the function at the command line + ```sh + cat hello.payload.json | fn run + ``` + +2. We received our function input through **stdin** + ```node + obj = JSON.parse(fs.readFileSync('/dev/stdin').toString()) + ``` + +3. We wrote our output to **stdout** + ```node + console.log + ``` + +4. We sent **stderr** to the server logs + ```node + console.error + ``` + + +# Next Up +## [Tutorial 2: Input Parameters](examples/tutorial/params) diff --git a/examples/tutorial/hello/php/hello.php b/examples/tutorial/hello/php/func.php similarity index 100% rename from examples/tutorial/hello/php/hello.php rename to examples/tutorial/hello/php/func.php diff --git a/examples/tutorial/hello/php/func.yaml b/examples/tutorial/hello/php/func.yaml index 027b012ee..b645b5960 100644 --- a/examples/tutorial/hello/php/func.yaml +++ b/examples/tutorial/hello/php/func.yaml @@ -1,5 +1,6 @@ -name: USERNAME/hello +name: carimura2/hello version: 0.0.1 +runtime: php +entrypoint: php func.php path: /hello -build: -- docker run --rm -v "$PWD":/worker -w /worker funcy/php:dev composer install +max_concurrency: 1 diff --git a/fn/init.go b/fn/init.go index f07d7bb0a..18142a58b 100644 --- a/fn/init.go +++ b/fn/init.go @@ -23,13 +23,14 @@ import ( var ( fileExtToRuntime = map[string]string{ - ".go": "go", - ".js": "node", - ".rb": "ruby", - ".py": "python", - ".rs": "rust", - ".cs": "dotnet", - ".fs": "dotnet", + ".go": "go", + ".js": "node", + ".rb": "ruby", + ".py": "python", + ".php": "php", + ".rs": "rust", + ".cs": "dotnet", + ".fs": "dotnet", } fnInitRuntimes []string diff --git a/fn/langs/base.go b/fn/langs/base.go index 606402f7b..1319ca014 100644 --- a/fn/langs/base.go +++ b/fn/langs/base.go @@ -11,6 +11,8 @@ func GetLangHelper(lang string) LangHelper { return &RubyLangHelper{} case "python": return &PythonHelper{} + case "php": + return &PhpLangHelper{} case "rust": return &RustLangHelper{} case "dotnet": diff --git a/fn/langs/php.go b/fn/langs/php.go new file mode 100644 index 000000000..e97dd5d6e --- /dev/null +++ b/fn/langs/php.go @@ -0,0 +1,49 @@ +package langs + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" +) + +type PhpLangHelper struct { + BaseHelper +} + +func (lh *PhpLangHelper) Entrypoint() string { + return "php func.php" +} + +func (lh *PhpLangHelper) HasPreBuild() bool { + return true +} + +func (lh *PhpLangHelper) PreBuild() error { + wd, err := os.Getwd() + if err != nil { + return err + } + + if !exists(filepath.Join(wd, "composer.json")) { + return nil + } + + pbcmd := fmt.Sprintf("docker run --rm -v %s:/worker -w /worker funcy/php:dev composer install", wd) + fmt.Println("Running prebuild command:", pbcmd) + parts := strings.Fields(pbcmd) + head := parts[0] + parts = parts[1:len(parts)] + cmd := exec.Command(head, parts...) + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + if err := cmd.Run(); err != nil { + return fmt.Errorf("error running docker build: %v", err) + } + return nil +} + +func (lh *PhpLangHelper) AfterBuild() error { + return nil +} diff --git a/fn/main.go b/fn/main.go index d26c14a4f..a2821c75d 100644 --- a/fn/main.go +++ b/fn/main.go @@ -37,7 +37,7 @@ func newFn() *cli.App { app.Version = vers.Version app.Authors = []cli.Author{{Name: "Oracle Corporation"}} app.Description = "Oracle Functions command line tools" - app.UsageText = `Check the manual at https://github.com/treeder/functions/blob/master/fn/README.md` + app.UsageText = `Check the manual at https://gitlab.oracledx.com/odx/functions/blob/master/fn/README.md` cli.AppHelpTemplate = `{{.Name}} {{.Version}}{{if .Description}} From 63b9e1ce203f96b6f004a78cf44d1dde7571c884 Mon Sep 17 00:00:00 2001 From: Chad Arimura Date: Fri, 26 May 2017 15:51:14 -0700 Subject: [PATCH 15/17] update php tutorial --- examples/tutorial/hello/php/.gitignore | 2 ++ examples/tutorial/hello/php/README.md | 36 +++++++++++++++-------- examples/tutorial/hello/php/composer.json | 1 + examples/tutorial/hello/php/func.php | 5 ++-- examples/tutorial/hello/php/func.yaml | 2 +- examples/tutorial/hello/ruby/README.md | 4 +-- 6 files changed, 33 insertions(+), 17 deletions(-) diff --git a/examples/tutorial/hello/php/.gitignore b/examples/tutorial/hello/php/.gitignore index 48b8bf907..fa3f387e3 100644 --- a/examples/tutorial/hello/php/.gitignore +++ b/examples/tutorial/hello/php/.gitignore @@ -1 +1,3 @@ vendor/ +func.yaml +composer.lock diff --git a/examples/tutorial/hello/php/README.md b/examples/tutorial/hello/php/README.md index d00232b40..7c15ea6d4 100644 --- a/examples/tutorial/hello/php/README.md +++ b/examples/tutorial/hello/php/README.md @@ -37,14 +37,21 @@ That's it! ### Note on Dependencies -```yml -name: USERNAME/hello -version: 0.0.1 -path: /hello -build: -- docker run --rm -v "$PWD":/worker -w /worker funcy/php:dev composer install +In PHP, you can create a [composer](https://getcomposer.org/) file in your function directory, then run: + +```sh +fn build ``` +This will rebuild your gems and vendor them. PHP doesn't pick them up automatically, so you'll have to add this to the top of your `func.php` file: + +```php +require 'vendor/autoload.php'; +``` + +Open `func.php` to see it in action. + + ### 3. Queue jobs for your function Now you can start jobs on your function. Let's quickly queue up a job to try it out. @@ -63,18 +70,23 @@ cat hello.payload.json | fn call phpapp /hello ``` 2. We received our function input through **stdin** - ```node - obj = JSON.parse(fs.readFileSync('/dev/stdin').toString()) + ```php + $payload = json_decode(file_get_contents("php://stdin"), true); ``` 3. We wrote our output to **stdout** - ```node - console.log + ```php + echo "Hello World!\n"; ``` 4. We sent **stderr** to the server logs - ```node - console.error + ```php + fwrite(STDERR, "--> this will go to stderr (server logs)\n"); + ``` + +5. We added PHP dependencies and enabled them using: + ```php + require 'vendor/autoload.php'; ``` diff --git a/examples/tutorial/hello/php/composer.json b/examples/tutorial/hello/php/composer.json index df8dd9cf8..6f1595fec 100644 --- a/examples/tutorial/hello/php/composer.json +++ b/examples/tutorial/hello/php/composer.json @@ -1,4 +1,5 @@ { "require": { + "monolog/monolog": "1.0.*" } } diff --git a/examples/tutorial/hello/php/func.php b/examples/tutorial/hello/php/func.php index 7828f1f95..50781499f 100644 --- a/examples/tutorial/hello/php/func.php +++ b/examples/tutorial/hello/php/func.php @@ -1,10 +1,11 @@ this will go to stderr (server logs)\n"); stream_set_blocking(STDIN, 0); $payload = json_decode(file_get_contents("php://stdin"), true); if (isset($payload['name'])) { - echo "Hello ", $payload['name'],"!\n\n"; + echo "Hello ", $payload['name'],"!\n"; } else { - echo "Hello World!\n\n"; + echo "Hello World!\n"; } diff --git a/examples/tutorial/hello/php/func.yaml b/examples/tutorial/hello/php/func.yaml index b645b5960..6036f79c7 100644 --- a/examples/tutorial/hello/php/func.yaml +++ b/examples/tutorial/hello/php/func.yaml @@ -1,5 +1,5 @@ name: carimura2/hello -version: 0.0.1 +version: 0.0.2 runtime: php entrypoint: php func.php path: /hello diff --git a/examples/tutorial/hello/ruby/README.md b/examples/tutorial/hello/ruby/README.md index 5f2ca5253..f348f9699 100644 --- a/examples/tutorial/hello/ruby/README.md +++ b/examples/tutorial/hello/ruby/README.md @@ -40,10 +40,10 @@ That's it! In Ruby, we create a [Gemfile](http://bundler.io/gemfile.html) file in your function directory, then run: ```sh -docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle install --standalone --clean +fn build ``` -Ruby doesn't pick up the gems automatically, so you'll have to add this to the top of your `func.rb` file: +This will rebuild your gems and vendor them. Ruby doesn't pick up the gems automatically, so you'll have to add this to the top of your `func.rb` file: ```ruby require_relative 'bundle/bundler/setup' From 1e90fc4459261d8abd6c188ce1e0692c32ddf093 Mon Sep 17 00:00:00 2001 From: Chad Arimura Date: Fri, 26 May 2017 17:01:39 -0700 Subject: [PATCH 16/17] consts --- api/server/server.go | 2 +- fn/apps.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/server/server.go b/api/server/server.go index 33faf35ba..73002ee95 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -212,7 +212,7 @@ func (s *Server) startGears(ctx context.Context) { logrus.WithError(err).Fatalln("Failed to serve functions API.") } - runHeader := ` + const runHeader = ` ____ __ / __ \_________ ______/ /__ / / / / ___/ __ / ___/ / _ \ diff --git a/fn/apps.go b/fn/apps.go index bca6f2a50..729637a2f 100644 --- a/fn/apps.go +++ b/fn/apps.go @@ -145,7 +145,7 @@ func (a *appsCmd) create(c *cli.Context) error { return fmt.Errorf("unexpected error: %v", err) } - createHeader := ` + const createHeader = ` ____ __ / __ \_________ ______/ /__ / / / / ___/ __ / ___/ / _ \ From e89be5eed778dabf3f60eab421acb7d810841757 Mon Sep 17 00:00:00 2001 From: Chad Arimura Date: Fri, 26 May 2017 17:20:23 -0700 Subject: [PATCH 17/17] 3 ticks to 1 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 761547de3..6492fb87d 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ curl http://localhost:8080/r/myapp/hello Or in a browser: [http://localhost:8080/r/myapp/hello](http://localhost:8080/r/myapp/hello) That's it! You just deployed your first function and called it. Now to update your function -you can update your code and run ```fn deploy myapp``` again. +you can update your code and run `fn deploy myapp` again. ## To Learn More