mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
Deploy will automatically create a route if it doesn't exist.
This commit is contained in:
@@ -32,21 +32,13 @@ The first time after you fork or after dependencies get updated, run:
|
||||
make dep
|
||||
```
|
||||
|
||||
Then after every change, run:
|
||||
Then after every change, run
|
||||
|
||||
```sh
|
||||
make build
|
||||
make run
|
||||
```
|
||||
|
||||
to build the `functions` binary.
|
||||
|
||||
### Run
|
||||
|
||||
```sh
|
||||
./functions
|
||||
```
|
||||
|
||||
will start IronFunctions using an embedded `Bolt` database running on port `8080`.
|
||||
to build and run the `functions` binary. It will start Functions using an embedded `Bolt` database running on port `8080`.
|
||||
|
||||
### Test
|
||||
|
||||
|
||||
4
Makefile
4
Makefile
@@ -20,8 +20,8 @@ test-build-arm:
|
||||
GOARCH=arm GOARM=7 $(MAKE) build
|
||||
GOARCH=arm64 $(MAKE) build
|
||||
|
||||
run:
|
||||
./functions
|
||||
run: build
|
||||
GIN_MODE=debug ./functions
|
||||
|
||||
docker-dep:
|
||||
# todo: need to create a dep tool image for this (or just ditch this)
|
||||
|
||||
@@ -131,6 +131,7 @@ 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)
|
||||
fn apps create myapp
|
||||
fn deploy myapp
|
||||
```
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ import (
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/boltdb/bolt"
|
||||
"gitlab.oracledx.com/odx/functions/api/models"
|
||||
"gitlab.oracledx.com/odx/functions/api/datastore/internal/datastoreutil"
|
||||
"gitlab.oracledx.com/odx/functions/api/models"
|
||||
)
|
||||
|
||||
type BoltDatastore struct {
|
||||
|
||||
@@ -46,6 +46,7 @@ func (s *Server) handleRouteUpdate(c *gin.Context) {
|
||||
}
|
||||
|
||||
if wroute.Route.Image != "" {
|
||||
// This was checking that an image exists, but it's too slow of an operation. Checks at runtime now.
|
||||
// err = s.Runner.EnsureImageExists(ctx, &task.Config{
|
||||
// Image: wroute.Route.Image,
|
||||
// })
|
||||
@@ -57,6 +58,10 @@ func (s *Server) handleRouteUpdate(c *gin.Context) {
|
||||
}
|
||||
|
||||
route, err := s.Datastore.UpdateRoute(ctx, wroute.Route)
|
||||
if err == models.ErrRoutesNotFound {
|
||||
// try insert then
|
||||
route, err = s.Datastore.InsertRoute(ctx, wroute.Route)
|
||||
}
|
||||
if err != nil {
|
||||
handleErrorResponse(c, err)
|
||||
return
|
||||
|
||||
34
fn/deploy.go
34
fn/deploy.go
@@ -5,9 +5,11 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
functions "github.com/iron-io/functions_go"
|
||||
"github.com/iron-io/functions_go/models"
|
||||
"github.com/urfave/cli"
|
||||
@@ -52,7 +54,7 @@ func (p *deploycmd) flags() []cli.Flag {
|
||||
Usage: "working directory",
|
||||
Destination: &p.wd,
|
||||
EnvVar: "WORK_DIR",
|
||||
Value: "./",
|
||||
// Value: "./",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "i",
|
||||
@@ -72,9 +74,14 @@ func (p *deploycmd) scan(c *cli.Context) error {
|
||||
p.verbwriter = verbwriter(p.verbose)
|
||||
|
||||
var walked bool
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
logrus.Fatalln("Couldn't get current directory:", err)
|
||||
}
|
||||
// logrus.Infoln("wd:", wd)
|
||||
|
||||
err := filepath.Walk(p.wd, func(path string, info os.FileInfo, err error) error {
|
||||
if path != p.wd && info.IsDir() {
|
||||
err = filepath.Walk(wd, func(path string, info os.FileInfo, err error) error {
|
||||
if path != wd && info.IsDir() {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
|
||||
@@ -97,7 +104,7 @@ func (p *deploycmd) scan(c *cli.Context) error {
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Fprintf(p.verbwriter, "file walk error: %s\n", err)
|
||||
fmt.Fprintf(p.verbwriter, "error: %s\n", err)
|
||||
}
|
||||
|
||||
if !walked {
|
||||
@@ -111,18 +118,23 @@ func (p *deploycmd) scan(c *cli.Context) error {
|
||||
// Parse functions file, bump version, build image, push to registry, and
|
||||
// finally it will update function's route. Optionally,
|
||||
// the route can be overriden inside the functions file.
|
||||
func (p *deploycmd) deploy(c *cli.Context, path string) error {
|
||||
fmt.Fprintln(p.verbwriter, "deploying", path)
|
||||
func (p *deploycmd) deploy(c *cli.Context, funcFilePath string) error {
|
||||
funcFileName := path.Base(funcFilePath)
|
||||
|
||||
err := c.App.Command("bump").Run(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
funcfile, err := buildfunc(p.verbwriter, path)
|
||||
funcfile, err := buildfunc(p.verbwriter, funcFileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if funcfile.Path == nil || *funcfile.Path == "" {
|
||||
dirName := "/" + path.Base(path.Dir(funcFilePath))
|
||||
funcfile.Path = &dirName
|
||||
}
|
||||
logrus.Infof("funcfile %+v", funcfile)
|
||||
|
||||
if p.skippush {
|
||||
return nil
|
||||
@@ -132,18 +144,18 @@ func (p *deploycmd) deploy(c *cli.Context, path string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return p.route(c, path, funcfile)
|
||||
return p.route(c, funcfile)
|
||||
}
|
||||
|
||||
func (p *deploycmd) route(c *cli.Context, path string, ff *funcfile) error {
|
||||
func (p *deploycmd) route(c *cli.Context, ff *funcfile) error {
|
||||
if err := resetBasePath(p.Configuration); err != nil {
|
||||
return fmt.Errorf("error setting endpoint: %v", err)
|
||||
}
|
||||
|
||||
routesCmd := routesCmd{client: apiClient()}
|
||||
rt := &models.Route{}
|
||||
routeWithFuncFile(c, rt)
|
||||
return routesCmd.patchRoute(p.appName, *ff.Path, rt)
|
||||
routeWithFuncFile(c, ff, rt)
|
||||
return routesCmd.patchRoute(c, p.appName, *ff.Path, rt)
|
||||
}
|
||||
|
||||
func expandEnvConfig(configs map[string]string) map[string]string {
|
||||
|
||||
68
fn/routes.go
68
fn/routes.go
@@ -287,26 +287,31 @@ func routeWithFlags(c *cli.Context, rt *models.Route) {
|
||||
}
|
||||
}
|
||||
|
||||
func routeWithFuncFile(c *cli.Context, rt *models.Route) {
|
||||
ff, err := loadFuncfile()
|
||||
if err == nil {
|
||||
if ff.FullName() != "" { // args take precedence
|
||||
rt.Image = ff.FullName()
|
||||
}
|
||||
if ff.Format != nil {
|
||||
rt.Format = *ff.Format
|
||||
}
|
||||
if ff.MaxConcurrency != nil {
|
||||
rt.MaxConcurrency = int32(*ff.MaxConcurrency)
|
||||
}
|
||||
if ff.Timeout != nil {
|
||||
to := int64(ff.Timeout.Seconds())
|
||||
rt.Timeout = &to
|
||||
}
|
||||
if rt.Path == "" && ff.Path != nil {
|
||||
rt.Path = *ff.Path
|
||||
func routeWithFuncFile(c *cli.Context, ff *funcfile, rt *models.Route) error {
|
||||
var err error
|
||||
if ff == nil {
|
||||
ff, err = loadFuncfile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if ff.FullName() != "" { // args take precedence
|
||||
rt.Image = ff.FullName()
|
||||
}
|
||||
if ff.Format != nil {
|
||||
rt.Format = *ff.Format
|
||||
}
|
||||
if ff.MaxConcurrency != nil {
|
||||
rt.MaxConcurrency = int32(*ff.MaxConcurrency)
|
||||
}
|
||||
if ff.Timeout != nil {
|
||||
to := int64(ff.Timeout.Seconds())
|
||||
rt.Timeout = &to
|
||||
}
|
||||
if rt.Path == "" && ff.Path != nil {
|
||||
rt.Path = *ff.Path
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *routesCmd) create(c *cli.Context) error {
|
||||
@@ -317,17 +322,21 @@ func (a *routesCmd) create(c *cli.Context) error {
|
||||
rt.Path = route
|
||||
rt.Image = c.Args().Get(2)
|
||||
|
||||
routeWithFuncFile(c, rt)
|
||||
routeWithFuncFile(c, nil, rt)
|
||||
routeWithFlags(c, rt)
|
||||
|
||||
if rt.Path == "" {
|
||||
return errors.New("error: route path is missing")
|
||||
return errors.New("route path is missing")
|
||||
}
|
||||
if rt.Image == "" {
|
||||
fmt.Println("No image specified, using `iron/hello`")
|
||||
rt.Image = "iron/hello"
|
||||
return errors.New("no image specified")
|
||||
}
|
||||
|
||||
return a.postRoute(c, appName, rt)
|
||||
}
|
||||
|
||||
func (a *routesCmd) postRoute(c *cli.Context, appName string, rt *fnmodels.Route) error {
|
||||
|
||||
body := &models.RouteWrapper{
|
||||
Route: rt,
|
||||
}
|
||||
@@ -354,7 +363,8 @@ func (a *routesCmd) create(c *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *routesCmd) patchRoute(appName, routePath string, r *fnmodels.Route) error {
|
||||
func (a *routesCmd) patchRoute(c *cli.Context, appName, routePath string, r *fnmodels.Route) error {
|
||||
// TODO: this getting the old version and merging should be on the server side, not here on the client.
|
||||
resp, err := a.client.Routes.GetAppsAppRoutesRoute(&apiroutes.GetAppsAppRoutesRouteParams{
|
||||
Context: context.Background(),
|
||||
App: appName,
|
||||
@@ -364,7 +374,9 @@ func (a *routesCmd) patchRoute(appName, routePath string, r *fnmodels.Route) err
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *apiroutes.GetAppsAppRoutesRouteNotFound:
|
||||
return fmt.Errorf("error: %s", err.(*apiroutes.GetAppsAppRoutesRouteNotFound).Payload.Error.Message)
|
||||
// return fmt.Errorf("error: %s", err.(*apiroutes.GetAppsAppRoutesRouteNotFound).Payload.Error.Message)
|
||||
// then insert it
|
||||
return a.postRoute(c, appName, r)
|
||||
case *apiroutes.GetAppsAppRoutesDefault:
|
||||
return fmt.Errorf("unexpected error: %s", err.(*apiroutes.GetAppsAppRoutesDefault).Payload.Error.Message)
|
||||
}
|
||||
@@ -446,10 +458,10 @@ func (a *routesCmd) update(c *cli.Context) error {
|
||||
route := cleanRoutePath(c.Args().Get(1))
|
||||
|
||||
rt := &models.Route{}
|
||||
routeWithFuncFile(c, rt)
|
||||
routeWithFuncFile(c, nil, rt)
|
||||
routeWithFlags(c, rt)
|
||||
|
||||
err := a.patchRoute(appName, route, rt)
|
||||
err := a.patchRoute(c, appName, route, rt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -470,7 +482,7 @@ func (a *routesCmd) configSet(c *cli.Context) error {
|
||||
|
||||
patchRoute.Config[key] = value
|
||||
|
||||
err := a.patchRoute(appName, route, &patchRoute)
|
||||
err := a.patchRoute(c, appName, route, &patchRoute)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -490,7 +502,7 @@ func (a *routesCmd) configUnset(c *cli.Context) error {
|
||||
|
||||
patchRoute.Config["-"+key] = ""
|
||||
|
||||
err := a.patchRoute(appName, route, &patchRoute)
|
||||
err := a.patchRoute(c, appName, route, &patchRoute)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user