Compare commits
5 Commits
0.7.51
...
0.8.0-alph
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9de10bc885 | ||
|
|
2d5446686a | ||
|
|
0d7d4f4a6a | ||
|
|
23c4171ece | ||
|
|
d8a1868fce |
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@@ -70,8 +70,8 @@ jobs:
|
||||
if [[ -z "$AKS_KUBECONFIG" ]];then
|
||||
echo "skip deploy test since no valid KUBECONFIG"
|
||||
else
|
||||
DEBUG=true ./build/fx deploy -n hello -p 12345 examples/functions/JavaScript/func.js
|
||||
./build/fx destroy hello
|
||||
DEBUG=true ./build/fx up -n hello -p 12345 examples/functions/JavaScript/func.js
|
||||
./build/fx down hello
|
||||
rm ${KUBECONFIG}
|
||||
fi
|
||||
|
||||
|
||||
93
.github/workflows/docker.yml
vendored
93
.github/workflows/docker.yml
vendored
@@ -1,57 +1,70 @@
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 12 * * *'
|
||||
on: [push]
|
||||
# schedule:
|
||||
# - cron: '0 12 * * *'
|
||||
name: docker
|
||||
jobs:
|
||||
Docker:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
docker_version:
|
||||
- 18.09
|
||||
# - 19.03
|
||||
# - 19.09
|
||||
docker_channel:
|
||||
- stable
|
||||
# - test
|
||||
steps:
|
||||
- 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
|
||||
uses: actions/docker/login@8cdf801b322af5f369e00d85e9cf3a7122f49108
|
||||
- name: login docker hub
|
||||
env:
|
||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||
run: |
|
||||
docker login --username $DOCKER_USERNAME --password $DOCKER_PASSWORD
|
||||
|
||||
- name: build-fx-go-image
|
||||
uses: actions/docker/cli@master
|
||||
with:
|
||||
args: build -t metrue/fx-go-base:latest -f api/asserts/dockerfiles/base/go/Dockerfile
|
||||
api/asserts/dockerfiles/base/go
|
||||
- name: build and publish fx d image
|
||||
if: always()
|
||||
run: |
|
||||
docker build -t metrue/fx-d-base:latest -f ./assets/dockerfiles/base/d/Dockerfile ./assets/dockerfiles/base/d
|
||||
docker push metrue/fx-d-base:latest
|
||||
|
||||
- name: push-fx-go-image
|
||||
uses: actions/docker/cli@master
|
||||
# - name: build and publish fx java image
|
||||
# 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:
|
||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||
with:
|
||||
args: push metrue/fx-go-base:latest
|
||||
run: |
|
||||
docker push metrue/fx-python-base:latest
|
||||
|
||||
- name: build-fx-rust-image
|
||||
uses: actions/docker/cli@master
|
||||
with:
|
||||
args: build -t metrue/fx-rust-base:latest -f api/asserts/dockerfiles/base/rust/Dockerfile
|
||||
api/asserts/dockerfiles/base/rust
|
||||
# - name: build and publish fx rust image
|
||||
# if: always()
|
||||
# run: |
|
||||
# docker build -t metrue/fx-rust-base:latest -f ./assets/dockerfiles/base/rust/Dockerfile ./assets/dockerfiles/base/python
|
||||
# docker push metrue/fx-rust-base:latest
|
||||
|
||||
- name: push-fx-rust-image
|
||||
uses: actions/docker/cli@master
|
||||
env:
|
||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||
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
|
||||
- name: build and publish fx julia image
|
||||
if: always()
|
||||
run: |
|
||||
docker build -t metrue/fx-julia-base:latest -f ./assets/dockerfiles/base/julia/Dockerfile ./assets/dockerfiles/base/julia
|
||||
docker push metrue/fx-julia-base:latest
|
||||
|
||||
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -66,8 +66,8 @@ jobs:
|
||||
run: |
|
||||
export KUBECONFIG=${HOME}/.kube/aks
|
||||
echo ${AKS_KUBECONFIG} | base64 -d > $KUBECONFIG
|
||||
DEBUG=true ./build/fx deploy -n hello -p 12345 examples/functions/JavaScript/func.js
|
||||
./build/fx destroy hello
|
||||
DEBUG=true ./build/fx up -n hello -p 12345 examples/functions/JavaScript/func.js
|
||||
./build/fx down hello
|
||||
rm ${KUBECONFIG}
|
||||
Release:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
@@ -70,14 +70,11 @@ func (d *Docker) BuildImage(ctx context.Context, workdir string, name string) er
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if os.Getenv("DEBUG") != "" {
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info(string(body))
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info(string(body))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -8,16 +8,18 @@ import (
|
||||
"time"
|
||||
|
||||
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"
|
||||
"github.com/metrue/fx/deploy"
|
||||
"github.com/metrue/fx/packer"
|
||||
"github.com/metrue/fx/types"
|
||||
"github.com/metrue/fx/utils"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Docker manage container
|
||||
type Docker struct {
|
||||
client *runtime.Docker
|
||||
localClient *runtime.Docker
|
||||
}
|
||||
|
||||
// CreateClient create a docker instance
|
||||
@@ -26,25 +28,50 @@ func CreateClient(ctx context.Context) (*Docker, error) {
|
||||
if err != nil {
|
||||
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
|
||||
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())
|
||||
defer os.RemoveAll(workdir)
|
||||
|
||||
if err := packer.PackIntoDir(fn, workdir); err != nil {
|
||||
log.Fatalf("could not pack function %v: %v", fn, err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := d.client.BuildImage(ctx, workdir, name); err != nil {
|
||||
if err := d.localClient.BuildImage(ctx, workdir, name); err != nil {
|
||||
log.Fatalf("could not build image: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
nameWithTag := name + ":latest"
|
||||
if err := d.client.ImageTag(ctx, name, nameWithTag); err != nil {
|
||||
log.Fatalf("could tag image: %v", err)
|
||||
if err := d.localClient.ImageTag(ctx, name, nameWithTag); err != nil {
|
||||
log.Fatalf("could not tag image: %v", 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
|
||||
var imgInfo dockerTypes.ImageInspect
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
return d.client.StartContainer(ctx, name, name, ports)
|
||||
return d.localClient.StartContainer(ctx, name, name, ports)
|
||||
}
|
||||
|
||||
// Update a container
|
||||
@@ -69,7 +96,7 @@ func (d *Docker) Update(ctx context.Context, name string) error {
|
||||
|
||||
// Destroy stop and remove container
|
||||
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
|
||||
|
||||
37
fx.go
37
fx.go
@@ -15,7 +15,7 @@ import (
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
const version = "0.7.51"
|
||||
const version = "0.8.0"
|
||||
|
||||
var cfg *config.Config
|
||||
|
||||
@@ -192,33 +192,6 @@ func main() {
|
||||
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",
|
||||
Usage: "destroy a service",
|
||||
@@ -227,14 +200,6 @@ func main() {
|
||||
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",
|
||||
Aliases: []string{"ls"},
|
||||
|
||||
2
go.mod
2
go.mod
@@ -31,7 +31,7 @@ require (
|
||||
github.com/pierrec/lz4 v0.0.0-20190222153722-062282ea0dcf // indirect
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/viper v1.4.0
|
||||
github.com/spf13/viper v1.5.0
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/ugorji/go v1.1.7 // indirect
|
||||
github.com/urfave/cli v1.22.1
|
||||
|
||||
6
go.sum
6
go.sum
@@ -279,6 +279,8 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/spf13/viper v1.5.0 h1:GpsTwfsQ27oS/Aha/6d1oD7tpKIqWnOA6tgOX9HHkt4=
|
||||
github.com/spf13/viper v1.5.0/go.mod h1:AkYRkVJF8TkSG/xet6PzXX+l39KhhXa2pdqVSxnTcn4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@@ -288,6 +290,8 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
|
||||
github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0=
|
||||
github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao=
|
||||
@@ -423,6 +427,8 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
||||
@@ -1,109 +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
|
||||
var bindings []types.PortBinding
|
||||
if os.Getenv("KUBECONFIG") != "" {
|
||||
deployer, err = k8sDeployer.Create()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bindings = []types.PortBinding{
|
||||
types.PortBinding{
|
||||
ServiceBindingPort: 80,
|
||||
ContainerExposePort: constants.FxContainerExposePort,
|
||||
},
|
||||
types.PortBinding{
|
||||
ServiceBindingPort: 443,
|
||||
ContainerExposePort: constants.FxContainerExposePort,
|
||||
},
|
||||
}
|
||||
} 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,
|
||||
},
|
||||
}
|
||||
}
|
||||
return deployer.Deploy(
|
||||
context.Background(),
|
||||
types.Func{Language: lang, Source: string(body)},
|
||||
name,
|
||||
bindings,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,37 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"github.com/apex/log"
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"github.com/metrue/fx/config"
|
||||
"github.com/metrue/fx/constants"
|
||||
api "github.com/metrue/fx/container_runtimes/docker/http"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/metrue/fx/deploy"
|
||||
dockerDeployer "github.com/metrue/fx/deploy/docker"
|
||||
k8sDeployer "github.com/metrue/fx/deploy/kubernetes"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Down command handle
|
||||
func Down(cfg config.Configer) HandleFunc {
|
||||
return func(ctx *cli.Context) error {
|
||||
containerID := ctx.Args()
|
||||
hosts, err := cfg.ListActiveMachines()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "list active machines failed: %v", err)
|
||||
}
|
||||
for name, host := range hosts {
|
||||
if err := api.MustCreate(host.Host, constants.AgentPort).
|
||||
Down(containerID); err != nil {
|
||||
return errors.Wrapf(err, "stop function on machine %s failed: %v", name, err)
|
||||
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
|
||||
}
|
||||
log.Infof("stop function on machine %s: %v", name, constants.CheckedSymbol)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
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/packer"
|
||||
"github.com/metrue/fx/provision"
|
||||
"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"
|
||||
@@ -31,8 +33,6 @@ func Up(cfg config.Configer) HandleFunc {
|
||||
funcFile := ctx.Args().First()
|
||||
name := ctx.String("name")
|
||||
port := ctx.Int("port")
|
||||
healtcheck := ctx.Bool("healthcheck")
|
||||
force := ctx.Bool("force")
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
@@ -48,69 +48,47 @@ func Up(cfg config.Configer) HandleFunc {
|
||||
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)
|
||||
|
||||
fn := types.Func{
|
||||
Language: lang,
|
||||
Source: string(body),
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
var deployer deploy.Deployer
|
||||
var bindings []types.PortBinding
|
||||
if os.Getenv("KUBECONFIG") != "" {
|
||||
deployer, err = k8sDeployer.Create()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := api.MustCreate(host.Host, constants.AgentPort).
|
||||
Up(api.UpOptions{
|
||||
Body: body,
|
||||
Lang: lang,
|
||||
Name: name,
|
||||
Port: port,
|
||||
HealtCheck: healtcheck,
|
||||
Project: project,
|
||||
}); err != nil {
|
||||
return errors.Wrapf(err, "up function %s(%s) to machine %s failed", name, funcFile, n)
|
||||
bindings = []types.PortBinding{
|
||||
types.PortBinding{
|
||||
ServiceBindingPort: 80,
|
||||
ContainerExposePort: constants.FxContainerExposePort,
|
||||
},
|
||||
types.PortBinding{
|
||||
ServiceBindingPort: 443,
|
||||
ContainerExposePort: constants.FxContainerExposePort,
|
||||
},
|
||||
}
|
||||
} 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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,18 +13,6 @@ run() {
|
||||
$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() {
|
||||
local lang=$1
|
||||
local tag=$2
|
||||
@@ -47,8 +35,6 @@ for lang in 'js' 'rb' 'py' 'go' 'php' 'java' 'd'; do
|
||||
run $lang $port
|
||||
((port++))
|
||||
|
||||
deploy $lang $port
|
||||
|
||||
build_image $lang "test-fx-image-build-${lang}"
|
||||
mkdir -p /tmp/${lang}/images
|
||||
export_image ${lang} /tmp/${lang}/images
|
||||
|
||||
Reference in New Issue
Block a user