Compare commits
4 Commits
0.7.3
...
0.7.3-alph
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa49a59feb | ||
|
|
c9d382d903 | ||
|
|
81e18e5b0d | ||
|
|
3882f843bf |
13
.github/workflows/ci.yml
vendored
13
.github/workflows/ci.yml
vendored
@@ -1,4 +1,4 @@
|
||||
on: push
|
||||
on: [push, pull_request]
|
||||
name: ci
|
||||
jobs:
|
||||
Test:
|
||||
@@ -61,9 +61,14 @@ 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
|
||||
rm ${KUBECONFIG}
|
||||
if [[ -z "$DOCKER_USERNAME" || -z "$DOCKER_PASSWORD" || -z "$AKS_KUBECONFIG" ]];then
|
||||
echo "skip deploy test since no DOCKER_USERNAME and DOCKER_PASSWORD set"
|
||||
else
|
||||
DEBUG=true ./build/fx deploy -n hello -p 12345 examples/functions/JavaScript/func.js
|
||||
./build/fx destroy hello
|
||||
rm ${KUBECONFIG}
|
||||
fi
|
||||
|
||||
Installation:
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: [Test]
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
run:
|
||||
concurrency: 4
|
||||
deadline: 10m
|
||||
timeout: 10m
|
||||
issues-exit-code: 1
|
||||
@@ -7,21 +6,25 @@ run:
|
||||
skip-dirs:
|
||||
- examples
|
||||
- api/images
|
||||
- test
|
||||
# skip-files:
|
||||
|
||||
- test/functions
|
||||
linters:
|
||||
enable:
|
||||
- megacheck
|
||||
- govet
|
||||
- deadcode
|
||||
# - gocyclo
|
||||
- golint
|
||||
- varcheck
|
||||
- structcheck
|
||||
- errcheck
|
||||
- dupl
|
||||
- ineffassign
|
||||
- goimports
|
||||
- stylecheck
|
||||
- gosec
|
||||
- interfacer
|
||||
- unconvert
|
||||
enable-all: false
|
||||
- goconst
|
||||
- gocyclo
|
||||
- misspell
|
||||
- unparam
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
- path: _test\.go
|
||||
linters:
|
||||
- gocyclo
|
||||
- goconst
|
||||
- errcheck
|
||||
- dupl
|
||||
- gosec
|
||||
|
||||
@@ -63,7 +63,7 @@ func (c *Config) Init() error {
|
||||
}
|
||||
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
return fmt.Errorf("Fatal error config file: %s", err)
|
||||
return fmt.Errorf("fatal error config file: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -69,10 +69,9 @@ func (d *Docker) BuildImage(ctx context.Context, workdir string, name string) er
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if os.Getenv("DEBUG") != "" {
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -88,10 +87,10 @@ func (d *Docker) PushImage(ctx context.Context, name string) (string, error) {
|
||||
username := os.Getenv("DOCKER_USERNAME")
|
||||
password := os.Getenv("DOCKER_PASSWORD")
|
||||
if username == "" || password == "" {
|
||||
return "", fmt.Errorf("DOCKER_USERNAME and DOCKER_PASSWORD required for push image to registy")
|
||||
return "", fmt.Errorf("DOCKER_USERNAME and DOCKER_PASSWORD required for push image to registry")
|
||||
}
|
||||
|
||||
// TODO support private registy, like Azure Container registry
|
||||
// TODO support private registry, like Azure Container registry
|
||||
authConfig := dockerTypes.AuthConfig{
|
||||
Username: username,
|
||||
Password: password,
|
||||
|
||||
@@ -45,7 +45,7 @@ func TestDocker(t *testing.T) {
|
||||
username := os.Getenv("DOCKER_USERNAME")
|
||||
password := os.Getenv("DOCKER_PASSWORD")
|
||||
if username == "" || password == "" {
|
||||
t.Skip("Skip push image test since DOCKER_USERNAME and DOCKER_PASSWORD not set in enviroment variable")
|
||||
t.Skip("Skip push image test since DOCKER_USERNAME and DOCKER_PASSWORD not set in environment variable")
|
||||
}
|
||||
|
||||
img, err := cli.PushImage(ctx, name)
|
||||
|
||||
@@ -2,10 +2,7 @@ package kubernetes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/google/uuid"
|
||||
runtime "github.com/metrue/fx/container_runtimes/docker/sdk"
|
||||
"github.com/metrue/fx/deploy"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
@@ -17,14 +14,11 @@ type K8S struct {
|
||||
*kubernetes.Clientset
|
||||
}
|
||||
|
||||
const namespace = "default"
|
||||
|
||||
// Create a k8s cluster client
|
||||
func Create() (*K8S, error) {
|
||||
kubeconfig := os.Getenv("KUBECONFIG")
|
||||
if kubeconfig == "" {
|
||||
return nil, fmt.Errorf("KUBECONFIG not given")
|
||||
}
|
||||
|
||||
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
|
||||
config, err := clientcmd.BuildConfigFromKubeconfigGetter("", clientcmd.NewDefaultClientConfigLoadingRules().Load)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -43,8 +37,6 @@ func (k *K8S) Deploy(
|
||||
name string,
|
||||
ports []int32,
|
||||
) error {
|
||||
namespace := "default"
|
||||
|
||||
dockerClient, err := runtime.CreateClient(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -61,7 +53,7 @@ func (k *K8S) Deploy(
|
||||
// be created automatically, then incoming traffic to Service will be forward to Pod.
|
||||
// Then we have no need to create Endpoint manually anymore.
|
||||
selector := map[string]string{
|
||||
"app": "fx-app-" + uuid.New().String(),
|
||||
"app": "fx-app-" + name,
|
||||
}
|
||||
|
||||
const replicas = int32(3)
|
||||
@@ -121,7 +113,6 @@ func (k *K8S) Update(ctx context.Context, name string) error {
|
||||
|
||||
// Destroy a service
|
||||
func (k *K8S) Destroy(ctx context.Context, name string) error {
|
||||
const namespace = "default"
|
||||
if err := k.DeleteService(namespace, name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -6,13 +6,15 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestK8SRunner(t *testing.T) {
|
||||
func TestK8SDeployer(t *testing.T) {
|
||||
workdir := "./fixture"
|
||||
name := "hello"
|
||||
ports := []int32{32300}
|
||||
kubeconfig := os.Getenv("KUBECONFIG")
|
||||
if kubeconfig == "" {
|
||||
t.Skip("skip test since no KUBECONFIG given in environment variable")
|
||||
username := os.Getenv("DOCKER_USERNAME")
|
||||
password := os.Getenv("DOCKER_PASSWORD")
|
||||
if kubeconfig == "" || username == "" || password == "" {
|
||||
t.Skip("skip test since no KUBECONFIG, DOCKER_USERNAME and DOCKER_PASSWORD given in environment variable")
|
||||
}
|
||||
k8s, err := Create()
|
||||
if err != nil {
|
||||
|
||||
@@ -33,7 +33,7 @@ func Deploy(cfg config.Configer) HandleFunc {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("deploy function %s (%s) failed: %v", err)
|
||||
log.Fatalf("deploy function %s (%s) failed: %v", name, funcFile, err)
|
||||
}
|
||||
log.Infof("function %s (%s) deployed successfully", name, funcFile)
|
||||
}()
|
||||
|
||||
@@ -14,7 +14,7 @@ type DockerPacker struct {
|
||||
box packr.Box
|
||||
}
|
||||
|
||||
func isHandler(lang string, name string) bool {
|
||||
func isHandler(name string) bool {
|
||||
basename := filepath.Base(name)
|
||||
nameWithoutExt := strings.TrimSuffix(basename, filepath.Ext(basename))
|
||||
return nameWithoutExt == "fx" ||
|
||||
@@ -39,7 +39,7 @@ func (p *DockerPacker) Pack(serviceName string, fn types.ServiceFunctionSource)
|
||||
}
|
||||
|
||||
// if preset's file is handler function of project, replace it with give one
|
||||
if isHandler(fn.Language, name) {
|
||||
if isHandler(name) {
|
||||
files = append(files, types.ProjectSourceFile{
|
||||
Path: strings.Replace(name, prefix, "", 1),
|
||||
Body: fn.Source,
|
||||
|
||||
@@ -42,8 +42,10 @@ func (l *LocalRunner) Run(script string) ([]byte, error) {
|
||||
params := strings.Split(script, " ")
|
||||
var cmd *exec.Cmd
|
||||
if len(params) > 1 {
|
||||
// nolint: gosec
|
||||
cmd = exec.Command(params[0], params[1:]...)
|
||||
} else {
|
||||
// nolint: gosec
|
||||
cmd = exec.Command(params[0])
|
||||
}
|
||||
return cmd.CombinedOutput()
|
||||
|
||||
@@ -16,9 +16,13 @@ run() {
|
||||
deploy() {
|
||||
local lang=$1
|
||||
local port=$2
|
||||
$fx deploy --name ${service}_${lang} --port ${port} test/functions/func.${lang}
|
||||
docker ps
|
||||
$fx destroy ${service}_${lang}
|
||||
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() {
|
||||
|
||||
@@ -22,6 +22,7 @@ func Download(filepath string, url string) (err error) {
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
// nolint: gosec
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -48,6 +49,7 @@ func Unzip(source string, target string) (err error) {
|
||||
}
|
||||
|
||||
for _, file := range reader.File {
|
||||
//nolint: gosec
|
||||
path := filepath.Join(target, file.Name)
|
||||
if file.FileInfo().IsDir() {
|
||||
if err := os.MkdirAll(path, file.Mode()); err != nil {
|
||||
@@ -262,7 +264,7 @@ func PairsToParams(pairs []string) map[string]string {
|
||||
func OutputJSON(v interface{}) error {
|
||||
bytes, err := json.MarshalIndent(v, "", "\t")
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could marshal %v : %v", v, err)
|
||||
return fmt.Errorf("could marshal %v : %v", v, err)
|
||||
}
|
||||
fmt.Println(string(bytes))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user