Compare commits
1 Commits
0.8.72-alp
...
0.8.73-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2298f39cca |
@@ -20,8 +20,6 @@ Poor man's function as a service.
|
||||
|
||||
## Introduction
|
||||
|
||||

|
||||
|
||||
fx is a tool to help you do Function as a Service on your own server, fx can make your stateless function a service in seconds, both Docker host and Kubernetes cluster supported. The most exciting thing is that you can write your functions with most programming languages.
|
||||
|
||||
Feel free hacking fx to support the languages not listed. Welcome to tweet me [@_metrue](https://twitter.com/_metrue) on Twitter, [@metrue](https://www.weibo.com/u/2165714507) on Weibo.
|
||||
@@ -211,8 +209,6 @@ But we would suggest you run `kubectl config current-context` to check if the cu
|
||||
|
||||
* Setup your own Kubernetes cluster
|
||||
|
||||

|
||||
|
||||
```shell
|
||||
fx infra create --type k3s --name fx-cluster-1 --master root@123.11.2.3 --agents 'root@1.1.1.1,root@2.2.2.2'
|
||||
```
|
||||
|
||||
@@ -106,7 +106,7 @@ func (c *Config) AddK8SCloud(name string, kubeconfig []byte) error {
|
||||
|
||||
cloud := map[string]string{
|
||||
"type": "k8s",
|
||||
"kubeConfig": kubecfg,
|
||||
"kubeconfig": kubecfg,
|
||||
}
|
||||
|
||||
return c.addCloud(name, cloud)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 294 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 78 KiB |
2
fx.go
2
fx.go
@@ -16,7 +16,7 @@ import (
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
const version = "0.8.72"
|
||||
const version = "0.8.73"
|
||||
|
||||
func init() {
|
||||
go checkForUpdate()
|
||||
|
||||
@@ -35,7 +35,6 @@ func setupK8S(masterInfo string, agentsInfo string) ([]byte, error) {
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(master, agents, len(agents))
|
||||
k8sOperator := k8s.New(master, agents)
|
||||
return k8sOperator.Provision()
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ func (k *Provisioner) HealthCheck() (bool, error) {
|
||||
func (k *Provisioner) SetupMaster() error {
|
||||
sshKeyFile, _ := infra.GetSSHKeyFile()
|
||||
ssh := sshOperator.New(k.master.IP).WithUser(k.master.User).WithKey(sshKeyFile)
|
||||
installCmd := fmt.Sprintf("curl -sLS https://get.k3s.io | INSTALL_K3S_EXEC='server --tls-san %s' INSTALL_K3S_VERSION='%s' sh -", k.master.IP, version)
|
||||
installCmd := fmt.Sprintf("curl -sLS https://get.k3s.io | INSTALL_K3S_EXEC='server --docker --tls-san %s' INSTALL_K3S_VERSION='%s' sh -", k.master.IP, version)
|
||||
if err := ssh.RunCommand(infra.Sudo(installCmd, k.master.User), sshOperator.CommandOptions{
|
||||
Stdout: os.Stdout,
|
||||
Stdin: os.Stdin,
|
||||
@@ -97,7 +97,7 @@ func (k *Provisioner) SetupAgent() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
const k3sExtraArgs = ""
|
||||
const k3sExtraArgs = "--docker"
|
||||
joinCmd := fmt.Sprintf("curl -fL https://get.k3s.io/ | K3S_URL='https://%s:6443' K3S_TOKEN='%s' INSTALL_K3S_VERSION='%s' sh -s - %s", k.master.IP, tok, version, k3sExtraArgs)
|
||||
for _, agent := range k.agents {
|
||||
ssh := sshOperator.New(agent.IP).WithUser(agent.User).WithKey(sshKeyFile)
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
package packer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/gobuffalo/packr"
|
||||
"github.com/metrue/fx/types"
|
||||
)
|
||||
|
||||
// DockerPacker pack a function source code to a Docker build-able project
|
||||
type DockerPacker struct {
|
||||
box packr.Box
|
||||
}
|
||||
|
||||
func isHandler(name string) bool {
|
||||
basename := filepath.Base(name)
|
||||
nameWithoutExt := strings.TrimSuffix(basename, filepath.Ext(basename))
|
||||
return nameWithoutExt == "fx" ||
|
||||
nameWithoutExt == "Fx" || // Fx is for Java
|
||||
nameWithoutExt == "mod" // mod.rs is for Rust
|
||||
}
|
||||
|
||||
// NewDockerPacker new a Docker packer
|
||||
func NewDockerPacker(box packr.Box) *DockerPacker {
|
||||
return &DockerPacker{box: box}
|
||||
}
|
||||
|
||||
// Pack pack a single function source code to be project
|
||||
func (p *DockerPacker) Pack(serviceName string, fn types.Func) (types.Project, error) {
|
||||
var files []types.ProjectSourceFile
|
||||
for _, name := range p.box.List() {
|
||||
prefix := fmt.Sprintf("%s/", fn.Language)
|
||||
if strings.HasPrefix(name, prefix) {
|
||||
content, err := p.box.FindString(name)
|
||||
if err != nil {
|
||||
return types.Project{}, err
|
||||
}
|
||||
|
||||
// if preset's file is handler function of project, replace it with give one
|
||||
if isHandler(name) {
|
||||
files = append(files, types.ProjectSourceFile{
|
||||
Path: strings.Replace(name, prefix, "", 1),
|
||||
Body: fn.Source,
|
||||
IsHandler: true,
|
||||
})
|
||||
} else {
|
||||
files = append(files, types.ProjectSourceFile{
|
||||
Path: strings.Replace(name, prefix, "", 1),
|
||||
Body: content,
|
||||
IsHandler: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return types.Project{
|
||||
Name: serviceName,
|
||||
Files: files,
|
||||
Language: fn.Language,
|
||||
}, nil
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package packer
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gobuffalo/packr"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/metrue/fx/types"
|
||||
)
|
||||
|
||||
func TestDockerPacker(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
box := packr.NewBox("./images")
|
||||
p := NewDockerPacker(box)
|
||||
|
||||
mockSource := `
|
||||
module.exports = ({a, b}) => {
|
||||
return a + b
|
||||
}
|
||||
`
|
||||
fn := types.Func{
|
||||
Language: "node",
|
||||
Source: mockSource,
|
||||
}
|
||||
|
||||
serviceName := "service-mock"
|
||||
project, err := p.Pack(serviceName, fn)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if project.Name != serviceName {
|
||||
t.Fatalf("should get %s but got %s", serviceName, project.Name)
|
||||
}
|
||||
|
||||
if project.Language != "node" {
|
||||
t.Fatal("incorrect Language")
|
||||
}
|
||||
|
||||
if len(project.Files) != 3 {
|
||||
t.Fatal("node project should have 3 files")
|
||||
}
|
||||
|
||||
for _, file := range project.Files {
|
||||
if file.Path == "fx.js" {
|
||||
if file.IsHandler == false {
|
||||
t.Fatal("fx.js should be handler")
|
||||
}
|
||||
if file.Body != mockSource {
|
||||
t.Fatalf("should get %s but got %v", mockSource, file.Body)
|
||||
}
|
||||
} else if file.Path == "Dockerfile" {
|
||||
if file.IsHandler == true {
|
||||
t.Fatalf("should get %v but got %v", false, file.IsHandler)
|
||||
}
|
||||
} else {
|
||||
if file.IsHandler == true {
|
||||
t.Fatalf("should get %v but %v", false, file.IsHandler)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,6 +154,14 @@ func merge(dest string, input ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func isHandler(name string) bool {
|
||||
basename := filepath.Base(name)
|
||||
nameWithoutExt := strings.TrimSuffix(basename, filepath.Ext(basename))
|
||||
return nameWithoutExt == "fx" ||
|
||||
nameWithoutExt == "Fx" || // Fx is for Java
|
||||
nameWithoutExt == "mod" // mod.rs is for Rust
|
||||
}
|
||||
|
||||
func langFromFileName(fileName string) string {
|
||||
extLangMap := map[string]string{
|
||||
".js": "node",
|
||||
|
||||
Reference in New Issue
Block a user