Compare commits

..

7 Commits

Author SHA1 Message Date
Minghe
2d5446686a fix docker workflow (#337) 2019-10-27 21:55:17 +08:00
Minghe
0d7d4f4a6a fix docker workflow (#336) 2019-10-19 08:02:42 +08:00
Minghe
23c4171ece update to up and down since we already merge them up (#335) 2019-10-18 09:56:22 +08:00
Minghe
d8a1868fce Merge "deploy" command to "up" command (#333) 2019-10-18 09:32:57 +08:00
Minghe Huang
d91a9959a8 bump version 2019-10-17 10:17:32 +08:00
Minghe
87e7c7d6ae fix the wrong binding when deploy function on Docker environment (#330) 2019-10-17 09:45:26 +08:00
Minghe
89c94daebc update contributors info (#329) 2019-10-16 23:57:42 +08:00
12 changed files with 194 additions and 338 deletions

View File

@@ -70,8 +70,8 @@ jobs:
if [[ -z "$AKS_KUBECONFIG" ]];then if [[ -z "$AKS_KUBECONFIG" ]];then
echo "skip deploy test since no valid KUBECONFIG" echo "skip deploy test since no valid KUBECONFIG"
else else
DEBUG=true ./build/fx deploy -n hello -p 12345 examples/functions/JavaScript/func.js DEBUG=true ./build/fx up -n hello -p 12345 examples/functions/JavaScript/func.js
./build/fx destroy hello ./build/fx down hello
rm ${KUBECONFIG} rm ${KUBECONFIG}
fi fi

View File

@@ -1,57 +1,70 @@
on: on: [push]
schedule: # schedule:
- cron: '0 12 * * *' # - cron: '0 12 * * *'
name: docker name: docker
jobs: jobs:
Docker: Docker:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy:
matrix:
docker_version:
- 18.09
# - 19.03
# - 19.09
docker_channel:
- stable
# - test
steps: steps:
- uses: actions/checkout@master - uses: actions/checkout@master
- name: setup docker
uses: docker-practice/actions-setup-docker@master
with:
docker_version: ${{ matrix.docker_version }}
docker_channel: ${{ matrix.docker_channel }}
- name: login - name: login docker hub
uses: actions/docker/login@8cdf801b322af5f369e00d85e9cf3a7122f49108
env: env:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
run: |
docker login --username $DOCKER_USERNAME --password $DOCKER_PASSWORD
- name: build-fx-go-image - name: build and publish fx d image
uses: actions/docker/cli@master if: always()
with: run: |
args: build -t metrue/fx-go-base:latest -f api/asserts/dockerfiles/base/go/Dockerfile docker build -t metrue/fx-d-base:latest -f ./assets/dockerfiles/base/d/Dockerfile ./assets/dockerfiles/base/d
api/asserts/dockerfiles/base/go docker push metrue/fx-d-base:latest
- name: push-fx-go-image # - name: build and publish fx java image
uses: actions/docker/cli@master # run: |
# docker build -t metrue/fx-go-base:latest -f ./assets/dockerfiles/base/java/Dockerfile ./assets/dockerfiles/base/java
# docker push metrue/fx-java-base:latest
- name: build and publish fx node image
if: always()
run: |
docker build -t metrue/fx-node-base:latest -f ./assets/dockerfiles/base/node/Dockerfile ./assets/dockerfiles/base/node
docker push metrue/fx-node-base:latest
- name: build and publish fx python image
if: always()
run: |
docker build -t metrue/fx-python-base:latest -f ./assets/dockerfiles/base/python/Dockerfile ./assets/dockerfiles/base/python
- name: publish fx python image
env: env:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
with: run: |
args: push metrue/fx-go-base:latest docker push metrue/fx-python-base:latest
- name: build-fx-rust-image # - name: build and publish fx rust image
uses: actions/docker/cli@master # if: always()
with: # run: |
args: build -t metrue/fx-rust-base:latest -f api/asserts/dockerfiles/base/rust/Dockerfile # docker build -t metrue/fx-rust-base:latest -f ./assets/dockerfiles/base/rust/Dockerfile ./assets/dockerfiles/base/python
api/asserts/dockerfiles/base/rust # docker push metrue/fx-rust-base:latest
- name: push-fx-rust-image - name: build and publish fx julia image
uses: actions/docker/cli@master if: always()
env: run: |
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} docker build -t metrue/fx-julia-base:latest -f ./assets/dockerfiles/base/julia/Dockerfile ./assets/dockerfiles/base/julia
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} docker push metrue/fx-julia-base:latest
with:
args: push metrue/fx-rust-base:latest
- name: build-fx-node-image
uses: actions/docker/cli@master
with:
args: build -t metrue/fx-node-base:latest -f api/asserts/dockerfiles/base/node/Dockerfile
api/asserts/dockerfiles/base/node
- name: push-fx-node-image
uses: actions/docker/cli@master
env:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
with:
args: push metrue/fx-node-base:latest

View File

@@ -66,8 +66,8 @@ jobs:
run: | run: |
export KUBECONFIG=${HOME}/.kube/aks export KUBECONFIG=${HOME}/.kube/aks
echo ${AKS_KUBECONFIG} | base64 -d > $KUBECONFIG echo ${AKS_KUBECONFIG} | base64 -d > $KUBECONFIG
DEBUG=true ./build/fx deploy -n hello -p 12345 examples/functions/JavaScript/func.js DEBUG=true ./build/fx up -n hello -p 12345 examples/functions/JavaScript/func.js
./build/fx destroy hello ./build/fx down hello
rm ${KUBECONFIG} rm ${KUBECONFIG}
Release: Release:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}

View File

@@ -304,33 +304,54 @@ Thank you to all the people who already contributed to fx!
<a href="https://github.com/metrue" target="_blank"> <a href="https://github.com/metrue" target="_blank">
<img alt="metrue" src="https://avatars2.githubusercontent.com/u/1001246?v=4&s=50" width="50"> <img alt="metrue" src="https://avatars2.githubusercontent.com/u/1001246?v=4&s=50" width="50">
</a> </a>
<a href="https://github.com/pplam" target="_blank">
<img alt="pplam" src="https://avatars2.githubusercontent.com/u/12783579?v=4&s=50" width="50">
</a>
<a href="https://github.com/muka" target="_blank"> <a href="https://github.com/muka" target="_blank">
<img alt="muka" src="https://avatars2.githubusercontent.com/u/1021269?v=4&s=50" width="50"> <img alt="muka" src="https://avatars2.githubusercontent.com/u/1021269?v=4&s=50" width="50">
</a> </a>
<a href="https://github.com/xwjdsh" target="_blank"> <a href="https://github.com/pplam" target="_blank">
<img alt="xwjdsh" src="https://avatars2.githubusercontent.com/u/11025519?v=4&s=50" width="50"> <img alt="pplam" src="https://avatars2.githubusercontent.com/u/12783579?v=4&s=50" width="50">
</a> </a>
<a href="https://github.com/mbesancon" target="_blank"> <a href="https://github.com/matbesancon" target="_blank">
<img alt="mbesancon" src="https://avatars2.githubusercontent.com/u/7623090?v=4&s=50" width="50"> <img alt="mbesancon" src="https://avatars2.githubusercontent.com/u/7623090?s=60&v=4" width="50">
</a>
<a href="https://github.com/avelino" target="_blank">
<img alt="avelino" src="https://avatars2.githubusercontent.com/u/31996?v=4&s=50" width="50">
</a>
<a href="https://github.com/DaidoujiChen" target="_blank">
<img alt="DaidoujiChen" src="https://avatars0.githubusercontent.com/u/670441?v=4&s=50" width="50">
</a> </a>
<a href="https://github.com/chlins" target="_blank"> <a href="https://github.com/chlins" target="_blank">
<img alt="chlins" src="https://avatars2.githubusercontent.com/u/31262637?v=4&s=50" width="50"> <img alt="chlins" src="https://avatars2.githubusercontent.com/u/31262637?v=4&s=50" width="50">
</a> </a>
<a href="https://github.com/xwjdsh" target="_blank">
<img alt="xwjdsh" src="https://avatars2.githubusercontent.com/u/11025519?v=4&s=50" width="50">
</a>
<a href="https://github.com/DaidoujiChen" target="_blank">
<img alt="DaidoujiChen" src="https://avatars0.githubusercontent.com/u/670441?v=4&s=50" width="50">
</a>
<a href="https://github.com/avelino" target="_blank">
<img alt="avelino" src="https://avatars2.githubusercontent.com/u/31996?v=4&s=50" width="50">
</a>
<a href="https://github.com/andre2007" target="_blank"> <a href="https://github.com/andre2007" target="_blank">
<img alt="andre2007" src="https://avatars1.githubusercontent.com/u/1451047?s=50&v=4" width="50"> <img alt="andre2007" src="https://avatars1.githubusercontent.com/u/1451047?s=50&v=4" width="50">
</a> </a>
<a href="https://github.com/polyrabbit" target="_blank">
<img alt="polyrabbit" src="https://avatars0.githubusercontent.com/u/2657334?s=60&v=4" width="50">
</a>
<a href="https://github.com/johnlunney" target="_blank">
<img alt="johnlunney" src="https://avatars3.githubusercontent.com/u/536947?s=60&v=4" width="50">
</a>
<a href="https://github.com/tbrand" target="_blank">
<img alt="tbrand" src="https://avatars0.githubusercontent.com/u/3483230?s=60&v=4" width="50">
</a>
<a href="https://github.com/steventhanna" target="_blank"> <a href="https://github.com/steventhanna" target="_blank">
<img alt="andre2007" src="https://avatars1.githubusercontent.com/u/2541678?s=50&v=4" width="50"> <img alt="andre2007" src="https://avatars1.githubusercontent.com/u/2541678?s=50&v=4" width="50">
</a> </a>
<a href="https://github.com/border-radius" target="_blank">
<img alt="border-radius" src="https://avatars0.githubusercontent.com/u/3204785?s=60&v=4" width="50">
</a>
<a href="https://github.com/Russtopia" target="_blank">
<img alt="Russtopia" src="https://avatars1.githubusercontent.com/u/2966177?s=60&v=4<Paste>" width="50">
</a>
<a href="https://github.com/FrontMage" target="_blank">
<img alt="FrontMage" src="https://avatars2.githubusercontent.com/u/17007026?s=60&v=4" width="50">
</a>
<a href="https://github.com/DropNib" target="_blank">
<img alt="DropNib" src="https://avatars0.githubusercontent.com/u/32019589?s=60&v=4" width="50">
</a>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@@ -70,14 +70,11 @@ func (d *Docker) BuildImage(ctx context.Context, workdir string, name string) er
return err return err
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if os.Getenv("DEBUG") != "" { if err != nil {
body, err := ioutil.ReadAll(resp.Body) return err
if err != nil {
return err
}
log.Info(string(body))
} }
log.Info(string(body))
return nil return nil
} }

View File

@@ -8,16 +8,18 @@ import (
"time" "time"
dockerTypes "github.com/docker/docker/api/types" dockerTypes "github.com/docker/docker/api/types"
dockerHTTP "github.com/metrue/fx/container_runtimes/docker/http"
runtime "github.com/metrue/fx/container_runtimes/docker/sdk" runtime "github.com/metrue/fx/container_runtimes/docker/sdk"
"github.com/metrue/fx/deploy" "github.com/metrue/fx/deploy"
"github.com/metrue/fx/packer" "github.com/metrue/fx/packer"
"github.com/metrue/fx/types" "github.com/metrue/fx/types"
"github.com/metrue/fx/utils" "github.com/metrue/fx/utils"
"github.com/pkg/errors"
) )
// Docker manage container // Docker manage container
type Docker struct { type Docker struct {
client *runtime.Docker localClient *runtime.Docker
} }
// CreateClient create a docker instance // CreateClient create a docker instance
@@ -26,25 +28,50 @@ func CreateClient(ctx context.Context) (*Docker, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &Docker{client: cli}, nil return &Docker{localClient: cli}, nil
} }
// Deploy create a Docker container from given image, and bind the constants.FxContainerExposePort to given port // Deploy create a Docker container from given image, and bind the constants.FxContainerExposePort to given port
func (d *Docker) Deploy(ctx context.Context, fn types.Func, name string, ports []types.PortBinding) error { func (d *Docker) Deploy(ctx context.Context, fn types.Func, name string, ports []types.PortBinding) error {
// if DOCKER_REMOTE_HOST and DOCKER_REMOTE_PORT given
// it means user is going to deploy service to remote host
host := os.Getenv("DOCKER_REMOTE_HOST")
port := os.Getenv("DOCKER_REMOTE_PORT")
if port != "" && host != "" {
httpClient, err := dockerHTTP.Create(host, port)
if err != nil {
return err
}
project, err := packer.Pack(name, fn)
if err != nil {
return errors.Wrapf(err, "could pack function %v (%s)", name, fn)
}
return httpClient.Up(dockerHTTP.UpOptions{
Body: []byte(fn.Source),
Lang: fn.Language,
Name: name,
Port: int(ports[0].ServiceBindingPort),
HealtCheck: false,
Project: project,
})
}
workdir := fmt.Sprintf("/tmp/fx-%d", time.Now().Unix()) workdir := fmt.Sprintf("/tmp/fx-%d", time.Now().Unix())
defer os.RemoveAll(workdir) defer os.RemoveAll(workdir)
if err := packer.PackIntoDir(fn, workdir); err != nil { if err := packer.PackIntoDir(fn, workdir); err != nil {
log.Fatalf("could not pack function %v: %v", fn, err)
return err return err
} }
if err := d.localClient.BuildImage(ctx, workdir, name); err != nil {
if err := d.client.BuildImage(ctx, workdir, name); err != nil { log.Fatalf("could not build image: %v", err)
return err return err
} }
nameWithTag := name + ":latest" nameWithTag := name + ":latest"
if err := d.client.ImageTag(ctx, name, nameWithTag); err != nil { if err := d.localClient.ImageTag(ctx, name, nameWithTag); err != nil {
log.Fatalf("could tag image: %v", err) log.Fatalf("could not tag image: %v", err)
return err return err
} }
@@ -54,12 +81,12 @@ func (d *Docker) Deploy(ctx context.Context, fn types.Func, name string, ports [
// But it takes some times waiting image ready after image built, we retry to make sure it ready here // But it takes some times waiting image ready after image built, we retry to make sure it ready here
var imgInfo dockerTypes.ImageInspect var imgInfo dockerTypes.ImageInspect
if err := utils.RunWithRetry(func() error { if err := utils.RunWithRetry(func() error {
return d.client.InspectImage(ctx, name, &imgInfo) return d.localClient.InspectImage(ctx, name, &imgInfo)
}, time.Second*1, 5); err != nil { }, time.Second*1, 5); err != nil {
return err return err
} }
return d.client.StartContainer(ctx, name, name, ports) return d.localClient.StartContainer(ctx, name, name, ports)
} }
// Update a container // Update a container
@@ -69,7 +96,7 @@ func (d *Docker) Update(ctx context.Context, name string) error {
// Destroy stop and remove container // Destroy stop and remove container
func (d *Docker) Destroy(ctx context.Context, name string) error { func (d *Docker) Destroy(ctx context.Context, name string) error {
return d.client.ContainerStop(ctx, name, nil) return d.localClient.ContainerStop(ctx, name, nil)
} }
// GetStatus get status of container // GetStatus get status of container

37
fx.go
View File

@@ -15,7 +15,7 @@ import (
"github.com/urfave/cli" "github.com/urfave/cli"
) )
const version = "0.7.5" const version = "0.8.0"
var cfg *config.Config var cfg *config.Config
@@ -192,33 +192,6 @@ func main() {
return handlers.Up(cfg)(c) return handlers.Up(cfg)(c)
}, },
}, },
{
Name: "deploy",
Usage: "deploy a function or a group of functions",
ArgsUsage: "[func.go func.js func.py func.rb ...]",
Flags: []cli.Flag{
cli.StringFlag{
Name: "name, n",
Value: uuid.New().String(),
Usage: "service name",
},
cli.IntFlag{
Name: "port, p",
Usage: "port number",
},
cli.BoolFlag{
Name: "healthcheck, hc",
Usage: "do a health check after service up",
},
cli.BoolFlag{
Name: "force, f",
Usage: "force deploy a function or functions",
},
},
Action: func(c *cli.Context) error {
return handlers.Deploy(cfg)(c)
},
},
{ {
Name: "down", Name: "down",
Usage: "destroy a service", Usage: "destroy a service",
@@ -227,14 +200,6 @@ func main() {
return handlers.Down(cfg)(c) return handlers.Down(cfg)(c)
}, },
}, },
{
Name: "destroy",
Usage: "destroy a service",
ArgsUsage: "[service 1, service 2, ....]",
Action: func(c *cli.Context) error {
return handlers.Destroy(cfg)(c)
},
},
{ {
Name: "list", Name: "list",
Aliases: []string{"ls"}, Aliases: []string{"ls"},

View File

@@ -1,102 +0,0 @@
package handlers
import (
"context"
"fmt"
"io/ioutil"
"os"
"github.com/apex/log"
"github.com/metrue/fx/config"
"github.com/metrue/fx/constants"
api "github.com/metrue/fx/container_runtimes/docker/http"
"github.com/metrue/fx/deploy"
dockerDeployer "github.com/metrue/fx/deploy/docker"
k8sDeployer "github.com/metrue/fx/deploy/kubernetes"
"github.com/metrue/fx/types"
"github.com/metrue/fx/utils"
"github.com/pkg/errors"
"github.com/urfave/cli"
)
// Deploy deploy handle function
func Deploy(cfg config.Configer) HandleFunc {
return func(ctx *cli.Context) (err error) {
funcFile := ctx.Args().First()
name := ctx.String("name")
port := ctx.Int("port")
force := ctx.Bool("force")
defer func() {
if r := recover(); r != nil {
log.Fatalf("fatal error happened: %v", r)
}
if err != nil {
log.Fatalf("deploy function %s (%s) failed: %v", name, funcFile, err)
}
log.Infof("function %s (%s) deployed successfully", name, funcFile)
}()
if port < PortRange.min || port > PortRange.max {
return fmt.Errorf("invalid port number: %d, port number should in range of %d - %d", port, PortRange.min, PortRange.max)
}
hosts, err := cfg.ListActiveMachines()
if err != nil {
return errors.Wrap(err, "list active machines failed")
}
if len(hosts) == 0 {
log.Warnf("no active machines")
return nil
}
// try to stop service firt
if force {
for n, host := range hosts {
if err := api.MustCreate(host.Host, constants.AgentPort).
Stop(name); err != nil {
log.Infof("stop function %s on machine %s failed: %v", name, n, err)
} else {
log.Infof("stop function %s on machine %s: %v", name, n, constants.CheckedSymbol)
}
}
}
body, err := ioutil.ReadFile(funcFile)
if err != nil {
return errors.Wrap(err, "read source failed")
}
lang := utils.GetLangFromFileName(funcFile)
var deployer deploy.Deployer
if os.Getenv("KUBECONFIG") != "" {
deployer, err = k8sDeployer.Create()
if err != nil {
return err
}
} else {
bctx := context.Background()
deployer, err = dockerDeployer.CreateClient(bctx)
if err != nil {
return err
}
}
// TODO multiple ports support
return deployer.Deploy(
context.Background(),
types.Func{Language: lang, Source: string(body)},
name,
[]types.PortBinding{
types.PortBinding{
ServiceBindingPort: 80,
ContainerExposePort: constants.FxContainerExposePort,
},
types.PortBinding{
ServiceBindingPort: 443,
ContainerExposePort: constants.FxContainerExposePort,
},
},
)
}
}

View File

@@ -1,38 +0,0 @@
package handlers
import (
"context"
"os"
"github.com/metrue/fx/config"
"github.com/metrue/fx/deploy"
dockerDeployer "github.com/metrue/fx/deploy/docker"
k8sDeployer "github.com/metrue/fx/deploy/kubernetes"
"github.com/urfave/cli"
)
// Destroy command handle
func Destroy(cfg config.Configer) HandleFunc {
return func(ctx *cli.Context) (err error) {
services := ctx.Args()
c := context.Background()
var runner deploy.Deployer
if os.Getenv("KUBECONFIG") != "" {
runner, err = k8sDeployer.Create()
if err != nil {
return err
}
} else {
runner, err = dockerDeployer.CreateClient(c)
if err != nil {
return err
}
}
for _, svc := range services {
if err := runner.Destroy(c, svc); err != nil {
return err
}
}
return nil
}
}

View File

@@ -1,28 +1,37 @@
package handlers package handlers
import ( import (
"github.com/apex/log" "context"
"os"
"github.com/metrue/fx/config" "github.com/metrue/fx/config"
"github.com/metrue/fx/constants" "github.com/metrue/fx/deploy"
api "github.com/metrue/fx/container_runtimes/docker/http" dockerDeployer "github.com/metrue/fx/deploy/docker"
"github.com/pkg/errors" k8sDeployer "github.com/metrue/fx/deploy/kubernetes"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
// Down command handle // Down command handle
func Down(cfg config.Configer) HandleFunc { func Down(cfg config.Configer) HandleFunc {
return func(ctx *cli.Context) error { return func(ctx *cli.Context) (err error) {
containerID := ctx.Args() services := ctx.Args()
hosts, err := cfg.ListActiveMachines() c := context.Background()
if err != nil { var runner deploy.Deployer
return errors.Wrapf(err, "list active machines failed: %v", err) if os.Getenv("KUBECONFIG") != "" {
} runner, err = k8sDeployer.Create()
for name, host := range hosts { if err != nil {
if err := api.MustCreate(host.Host, constants.AgentPort). return err
Down(containerID); err != nil { }
return errors.Wrapf(err, "stop function on machine %s failed: %v", name, err) } else {
runner, err = dockerDeployer.CreateClient(c)
if err != nil {
return err
}
}
for _, svc := range services {
if err := runner.Destroy(c, svc); err != nil {
return err
} }
log.Infof("stop function on machine %s: %v", name, constants.CheckedSymbol)
} }
return nil return nil
} }

View File

@@ -1,15 +1,17 @@
package handlers package handlers
import ( import (
"context"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os"
"github.com/apex/log" "github.com/apex/log"
"github.com/metrue/fx/config" "github.com/metrue/fx/config"
"github.com/metrue/fx/constants" "github.com/metrue/fx/constants"
api "github.com/metrue/fx/container_runtimes/docker/http" "github.com/metrue/fx/deploy"
"github.com/metrue/fx/packer" dockerDeployer "github.com/metrue/fx/deploy/docker"
"github.com/metrue/fx/provision" k8sDeployer "github.com/metrue/fx/deploy/kubernetes"
"github.com/metrue/fx/types" "github.com/metrue/fx/types"
"github.com/metrue/fx/utils" "github.com/metrue/fx/utils"
"github.com/pkg/errors" "github.com/pkg/errors"
@@ -31,8 +33,6 @@ func Up(cfg config.Configer) HandleFunc {
funcFile := ctx.Args().First() funcFile := ctx.Args().First()
name := ctx.String("name") name := ctx.String("name")
port := ctx.Int("port") port := ctx.Int("port")
healtcheck := ctx.Bool("healthcheck")
force := ctx.Bool("force")
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
@@ -48,69 +48,47 @@ func Up(cfg config.Configer) HandleFunc {
if port < PortRange.min || port > PortRange.max { if port < PortRange.min || port > PortRange.max {
return fmt.Errorf("invalid port number: %d, port number should in range of %d - %d", port, PortRange.min, PortRange.max) return fmt.Errorf("invalid port number: %d, port number should in range of %d - %d", port, PortRange.min, PortRange.max)
} }
hosts, err := cfg.ListActiveMachines()
if err != nil {
return errors.Wrap(err, "list active machines failed")
}
if len(hosts) == 0 {
log.Warnf("no active machines")
return nil
}
// try to stop service firt
if force {
for n, host := range hosts {
if err := api.MustCreate(host.Host, constants.AgentPort).
Stop(name); err != nil {
log.Infof("stop function %s on machine %s failed: %v", name, n, err)
} else {
log.Infof("stop function %s on machine %s: %v", name, n, constants.CheckedSymbol)
}
}
}
body, err := ioutil.ReadFile(funcFile) body, err := ioutil.ReadFile(funcFile)
if err != nil { if err != nil {
return errors.Wrap(err, "read source failed") return errors.Wrap(err, "read source failed")
} }
lang := utils.GetLangFromFileName(funcFile) lang := utils.GetLangFromFileName(funcFile)
var deployer deploy.Deployer
fn := types.Func{ var bindings []types.PortBinding
Language: lang, if os.Getenv("KUBECONFIG") != "" {
Source: string(body), deployer, err = k8sDeployer.Create()
} if err != nil {
return err
project, err := packer.Pack(name, fn)
if err != nil {
return errors.Wrapf(err, "could pack function %s (%s)", name, funcFile)
}
for n, host := range hosts {
if !host.Provisioned {
provisionor := provision.New(host)
if err := provisionor.Start(); err != nil {
return errors.Wrapf(err, "could not provision %s", n)
}
log.Infof("provision machine %v: %s", n, constants.CheckedSymbol)
if err := cfg.UpdateProvisionedStatus(n, true); err != nil {
return errors.Wrap(err, "update machine provision status failed")
}
} }
bindings = []types.PortBinding{
if err := api.MustCreate(host.Host, constants.AgentPort). types.PortBinding{
Up(api.UpOptions{ ServiceBindingPort: 80,
Body: body, ContainerExposePort: constants.FxContainerExposePort,
Lang: lang, },
Name: name, types.PortBinding{
Port: port, ServiceBindingPort: 443,
HealtCheck: healtcheck, ContainerExposePort: constants.FxContainerExposePort,
Project: project, },
}); err != nil { }
return errors.Wrapf(err, "up function %s(%s) to machine %s failed", name, funcFile, n) } else {
bctx := context.Background()
deployer, err = dockerDeployer.CreateClient(bctx)
if err != nil {
return err
}
bindings = []types.PortBinding{
types.PortBinding{
ServiceBindingPort: int32(port),
ContainerExposePort: constants.FxContainerExposePort,
},
} }
log.Infof("up function %s(%s) to machine %s: %v", name, funcFile, n, constants.CheckedSymbol)
} }
return nil return deployer.Deploy(
context.Background(),
types.Func{Language: lang, Source: string(body)},
name,
bindings,
)
} }
} }

View File

@@ -13,18 +13,6 @@ run() {
$fx down ${service}_${lang} # | grep "Down Service ${service}" $fx down ${service}_${lang} # | grep "Down Service ${service}"
} }
deploy() {
local lang=$1
local port=$2
if [[ -z "$DOCKER_USERNAME" || -z "$DOCKER_PASSWORD" ]];then
echo "skip deploy test since no DOCKER_USERNAME and DOCKER_PASSWORD set"
else
$fx deploy --name ${service}-${lang} --port ${port} test/functions/func.${lang}
docker ps
$fx destroy ${service}-${lang}
fi
}
build_image() { build_image() {
local lang=$1 local lang=$1
local tag=$2 local tag=$2
@@ -47,8 +35,6 @@ for lang in 'js' 'rb' 'py' 'go' 'php' 'java' 'd'; do
run $lang $port run $lang $port
((port++)) ((port++))
deploy $lang $port
build_image $lang "test-fx-image-build-${lang}" build_image $lang "test-fx-image-build-${lang}"
mkdir -p /tmp/${lang}/images mkdir -p /tmp/${lang}/images
export_image ${lang} /tmp/${lang}/images export_image ${lang} /tmp/${lang}/images