Compare commits

...

58 Commits

Author SHA1 Message Date
dependabot-preview[bot]
2123a0fec4 Bump github.com/apex/log from 1.3.0 to 1.6.0 (#558)
Bumps [github.com/apex/log](https://github.com/apex/log) from 1.3.0 to 1.6.0.
- [Release notes](https://github.com/apex/log/releases)
- [Changelog](https://github.com/apex/log/blob/master/History.md)
- [Commits](https://github.com/apex/log/compare/v1.3.0...v1.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-07-14 08:33:11 +08:00
Minghe
9e9cdeb3ee enable timestamp on image (#556)
* enable timestamp on image

* fix name issue
2020-07-09 21:25:55 +08:00
Minghe Huang
c17434703e disable k8s relate unit test for now 2020-06-28 00:48:19 +08:00
Minghe Huang
0644eb285a disable k8s relate unit test for now 2020-06-28 00:38:34 +08:00
Minghe
0f4120c2c8 fix wrong way to take user and host from env (#552) 2020-06-28 00:27:54 +08:00
FrontMage
ba43561f40 Rust multistage build (#550)
* fix get request not accepted

* use mutli-stage docker build to minimize final image

Co-authored-by: Minghe <h.minghe@gmail.com>
2020-06-17 14:16:31 +08:00
Minghe Huang
046226b580 add vistors 2020-06-13 13:10:32 +08:00
dependabot-preview[bot]
cd391e63c1 Bump github.com/stretchr/testify from 1.6.0 to 1.6.1 (#546)
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.6.0 to 1.6.1.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.6.0...v1.6.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-06-06 21:14:10 +08:00
FrontMage
ed5fc4adaf fix get request not accepted (#547) 2020-06-06 21:13:48 +08:00
Viktor Barzin
eb5a1d4fc5 Fix typo (#545) 2020-06-01 17:58:04 -07:00
Viktor Barzin
4cd8bde604 Fix typo (#544) 2020-06-01 17:57:22 -07:00
dependabot-preview[bot]
c73aedb68d Bump github.com/stretchr/testify from 1.5.1 to 1.6.0 (#543)
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.5.1 to 1.6.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.5.1...v1.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-06-01 10:58:21 +08:00
dependabot-preview[bot]
e9ee8ec1f5 Bump github.com/apex/log from 1.1.4 to 1.3.0 (#541)
Bumps [github.com/apex/log](https://github.com/apex/log) from 1.1.4 to 1.3.0.
- [Release notes](https://github.com/apex/log/releases)
- [Changelog](https://github.com/apex/log/blob/master/History.md)
- [Commits](https://github.com/apex/log/compare/v1.1.4...v1.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-05-27 16:24:58 +08:00
Minghe
fd6b1947a5 adopt the swagger-stats as API operation metrics collection tool. (#537)
* adopt the swagger-stats as API operation metrics collection tool.

FYI: https://github.com/slanatech/swagger-stats

* no need change

* naming

* fix test

* move deps to base

* bump version

* update
2020-05-27 16:24:42 +08:00
dependabot-preview[bot]
aeb373190a Bump github.com/otiai10/copy from 1.1.1 to 1.2.0 (#540)
Bumps [github.com/otiai10/copy](https://github.com/otiai10/copy) from 1.1.1 to 1.2.0.
- [Release notes](https://github.com/otiai10/copy/releases)
- [Commits](https://github.com/otiai10/copy/compare/v1.1.1...v1.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-05-26 11:42:42 +08:00
Minghe
a74b086219 when destroy container, should remove it also (#530) 2020-05-16 20:01:19 +08:00
Minghe
6214581ca8 Expose logs when container started but exited with errors (#527)
* expose the error message of start failure
* disable container auto-remove, only remove it when it fails to start
* call /containers/id/logs endpoint to get the logs
2020-05-16 18:11:02 +08:00
Minghe Huang
63bc06a993 add task name
replace spinner
2020-05-07 20:01:28 +08:00
Minghe Huang
833b7d06a3 bump version 2020-05-07 18:23:02 +08:00
dependabot-preview[bot]
1ae68f1076 Bump github.com/briandowns/spinner from 1.10.0 to 1.11.1 (#521)
Bumps [github.com/briandowns/spinner](https://github.com/briandowns/spinner) from 1.10.0 to 1.11.1.
- [Release notes](https://github.com/briandowns/spinner/releases)
- [Commits](https://github.com/briandowns/spinner/compare/v1.10.0...v1.11.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Minghe <h.minghe@gmail.com>
2020-05-07 16:53:04 +08:00
Minghe
5ce61ef200 Fix the wrong arch of target host (#524)
* Fix the wrong arch of target host,
* get the OS arch with `uname -a`
* refactor the SSHConnectionTimeout constant
* only provision on remote host
2020-05-07 16:52:45 +08:00
dependabot-preview[bot]
3923c3451f Bump github.com/gin-gonic/gin from 1.6.2 to 1.6.3 (#522)
Bumps [github.com/gin-gonic/gin](https://github.com/gin-gonic/gin) from 1.6.2 to 1.6.3.
- [Release notes](https://github.com/gin-gonic/gin/releases)
- [Changelog](https://github.com/gin-gonic/gin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gin-gonic/gin/compare/v1.6.2...v1.6.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-05-05 10:02:49 +08:00
Massimiliano Mirra
8741db25b6 use lighter-weight node image (#518) 2020-04-28 10:55:13 +08:00
Minghe
16d20b23a7 fix gosec issue (#519) 2020-04-28 10:43:04 +08:00
dependabot-preview[bot]
5028ba7694 Bump github.com/urfave/cli from 1.22.3 to 1.22.4 (#504)
Bumps [github.com/urfave/cli](https://github.com/urfave/cli) from 1.22.3 to 1.22.4.
- [Release notes](https://github.com/urfave/cli/releases)
- [Changelog](https://github.com/urfave/cli/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/urfave/cli/compare/v1.22.3...v1.22.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Minghe <h.minghe@gmail.com>
2020-04-23 12:10:59 +08:00
dependabot-preview[bot]
a324fab432 Bump github.com/apex/log from 1.1.2 to 1.1.4 (#516)
Bumps [github.com/apex/log](https://github.com/apex/log) from 1.1.2 to 1.1.4.
- [Release notes](https://github.com/apex/log/releases)
- [Changelog](https://github.com/apex/log/blob/master/History.md)
- [Commits](https://github.com/apex/log/compare/v1.1.2...v1.1.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-23 11:55:45 +08:00
Minghe Huang
275ec78ad0 disable rust 2020-04-10 19:34:24 +08:00
Minghe
2455eb215e commit packrd file (#513) 2020-04-10 19:10:47 +08:00
Minghe
3b3503de1e add missing (#511) 2020-04-10 18:29:47 +08:00
Minghe
7135633b60 should come back (#509) 2020-04-10 17:32:55 +08:00
Minghe
b69cf16250 should not exit with 0 when panic happens (#507) 2020-04-10 17:10:03 +08:00
dependabot-preview[bot]
4527da6251 Bump github.com/spf13/viper from 1.6.2 to 1.6.3 (#506)
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.6.2 to 1.6.3.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.6.2...v1.6.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-10 09:38:35 +08:00
dependabot-preview[bot]
2a17ea6131 Bump github.com/gin-gonic/gin from 1.4.0 to 1.6.2 (#503)
Bumps [github.com/gin-gonic/gin](https://github.com/gin-gonic/gin) from 1.4.0 to 1.6.2.
- [Release notes](https://github.com/gin-gonic/gin/releases)
- [Changelog](https://github.com/gin-gonic/gin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gin-gonic/gin/compare/v1.4.0...v1.6.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-28 12:03:06 +08:00
dependabot-preview[bot]
5adca0dd2f Bump github.com/briandowns/spinner from 1.9.0 to 1.10.0 (#501)
Bumps [github.com/briandowns/spinner](https://github.com/briandowns/spinner) from 1.9.0 to 1.10.0.
- [Release notes](https://github.com/briandowns/spinner/releases)
- [Commits](https://github.com/briandowns/spinner/compare/v1.9.0...v1.10.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-26 10:16:58 +08:00
Minghe
521a9e64a2 update docs (#498) 2020-03-20 18:54:30 +08:00
Minghe Huang
bfe8dc4249 bump version 2020-03-19 22:15:06 +08:00
Minghe
b569820d3e Provisioners (#495)
* seperate privisioners by platforms
* refactor provisioner
* fix image build
2020-03-19 21:53:31 +08:00
dependabot-preview[bot]
99b3696b29 Bump github.com/golang/mock from 1.4.2 to 1.4.3 (#486)
Bumps [github.com/golang/mock](https://github.com/golang/mock) from 1.4.2 to 1.4.3.
- [Release notes](https://github.com/golang/mock/releases)
- [Changelog](https://github.com/golang/mock/blob/master/.goreleaser.yml)
- [Commits](https://github.com/golang/mock/compare/v1.4.2...v1.4.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-19 17:51:22 +08:00
Minghe
779679a809 Remove 'fx call' and 'fx doctor' 2020-03-19 16:54:45 +08:00
Minghe
ec49f75717 update readme (#491) 2020-03-19 13:37:39 +08:00
Minghe
23598ce1c6 update docs (#490) 2020-03-19 13:30:28 +08:00
Minghe
2831949814 Refactor driver and privioner (#489) 2020-03-19 11:28:52 +08:00
Minghe
e712e3d0e2 Simplify fx infra (#485)
* add --host and --kubeconf to `fx up`
* remove `fx infra list` and `fx infra use`
* put assets into skip dir for golangci

* fix lint issue

* upgrade go-ssh-client to consume the 'Connectable' API, enable more
friendly SSH connection error message

* parse 'host' and 'kubeconf' for `fx list` and `fx down` also

* refactor parse

* clean infra stuff
2020-03-18 09:00:14 +08:00
Minghe
7df1c64740 name the box (#481) 2020-03-15 12:55:52 +08:00
Minghe
91325f9ca3 commit packr-ed files (#480) 2020-03-15 08:36:46 +08:00
Minghe Huang
7326325c19 release v0.9.3 2020-03-14 20:46:09 +08:00
dependabot-preview[bot]
59e195fa94 Bump github.com/golang/mock from 1.4.1 to 1.4.2 (#479)
Bumps [github.com/golang/mock](https://github.com/golang/mock) from 1.4.1 to 1.4.2.
- [Release notes](https://github.com/golang/mock/releases)
- [Changelog](https://github.com/golang/mock/blob/master/.goreleaser.yml)
- [Commits](https://github.com/golang/mock/compare/v1.4.1...v1.4.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-14 20:37:52 +08:00
dependabot-preview[bot]
5ed4f8795a Bump github.com/gobuffalo/packr/v2 from 2.5.1 to 2.8.0 (#476)
Bumps [github.com/gobuffalo/packr/v2](https://github.com/gobuffalo/packr) from 2.5.1 to 2.8.0.
- [Release notes](https://github.com/gobuffalo/packr/releases)
- [Changelog](https://github.com/gobuffalo/packr/blob/master/.goreleaser.yml)
- [Commits](https://github.com/gobuffalo/packr/compare/v2.5.1...v2.8.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-11 11:48:19 +08:00
dependabot-preview[bot]
a02e7e66af Bump github.com/urfave/cli from 1.22.2 to 1.22.3 (#477)
Bumps [github.com/urfave/cli](https://github.com/urfave/cli) from 1.22.2 to 1.22.3.
- [Release notes](https://github.com/urfave/cli/releases)
- [Changelog](https://github.com/urfave/cli/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/urfave/cli/compare/v1.22.2...v1.22.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Minghe <h.minghe@gmail.com>
2020-03-11 11:48:02 +08:00
dependabot-preview[bot]
9c1d093bb8 Bump github.com/otiai10/copy from 1.0.2 to 1.1.1 (#474)
Bumps [github.com/otiai10/copy](https://github.com/otiai10/copy) from 1.0.2 to 1.1.1.
- [Release notes](https://github.com/otiai10/copy/releases)
- [Commits](https://github.com/otiai10/copy/compare/v1.0.2...v1.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Minghe <h.minghe@gmail.com>
2020-03-11 09:12:51 +08:00
Minghe
302877d4b4 Fn and deps (#475) 2020-03-11 08:59:47 +08:00
Minghe
871bb29dbe Bundler (#473)
* refactor bundler
* enable unit test
2020-03-10 22:49:14 +08:00
Minghe Huang
3be144f644 clean up no need files 2020-03-10 10:18:07 +08:00
Minghe
2560dc23fc fix the wrong destination of copy issue (#466)
* fix the wrong destination of copy issue
* bump up version
2020-03-01 15:58:45 +08:00
dependabot-preview[bot]
3d6c3d10bf Bump github.com/golang/mock from 1.4.0 to 1.4.1 (#464)
Bumps [github.com/golang/mock](https://github.com/golang/mock) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/golang/mock/releases)
- [Changelog](https://github.com/golang/mock/blob/master/.goreleaser.yml)
- [Commits](https://github.com/golang/mock/compare/v1.4.0...v1.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-28 09:27:02 +08:00
Minghe
5f811693f1 bump up version 2020-02-21 17:28:07 +08:00
Minghe
0068fb92eb support 'format' option in 'fx list' (#462) 2020-02-21 17:26:39 +08:00
dependabot-preview[bot]
71174ead45 Bump github.com/stretchr/testify from 1.4.0 to 1.5.1 (#459)
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.4.0 to 1.5.1.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.4.0...v1.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-21 15:10:47 +08:00
180 changed files with 5055 additions and 3667 deletions

View File

@@ -19,8 +19,7 @@ jobs:
- name: lint
run: |
docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint \
golangci-lint run -v
make lint
- name: unit test
env:
@@ -28,7 +27,7 @@ jobs:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
run: |
export KUBECONFIG="$(kind get kubeconfig-path)"
# export KUBECONFIG="$(kind get kubeconfig-path)"
make unit-test
bash <(curl -s https://codecov.io/bash) -t ${CODECOV_TOKEN}
@@ -43,11 +42,6 @@ jobs:
make docker-build
make test
# make docker-publish #TODO in release workflow
- name: test fx docker cloud
run: |
make start_docker_infra
make test_docker_infra
make stop_docker_infra
- name: test fx cli
env:

View File

@@ -32,7 +32,7 @@ jobs:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
run: |
export KUBECONFIG="$(kind get kubeconfig-path)"
# export KUBECONFIG="$(kind get kubeconfig-path)"
make unit-test
- name: build fx

View File

@@ -7,6 +7,8 @@ run:
- examples
- api/images
- test/functions
- assets/
- bundler/go/assets
linters:
enable:
- goimports

View File

@@ -4,7 +4,8 @@ DOCKER_REMOTE_HOST_ADDR ?= "127.0.0.1"
DOCKER_REMOTE_HOST_USER ?= $(whoami)
lint:
golangci-lint run
docker pull golangci/golangci-lint
docker run --rm -v $(CURDIR):/app -w /app golangci/golangci-lint golangci-lint run -v
generate:
packr
@@ -26,13 +27,13 @@ clean:
rm -rf ${DIST_DIR}
unit-test:
CI=true ./scripts/coverage.sh
./scripts/coverage.sh
cli-test-ci:
./scripts/test_cli.sh 'js'
cli-test:
./scripts/test_cli.sh 'js rb py go php java d rs pl'
./scripts/test_cli.sh 'js rb py go java d pl'
http-test:
./scripts/http_test.sh

View File

@@ -8,16 +8,14 @@ Poor man's function as a service.
[![CodeCov](https://codecov.io/gh/metrue/fx/branch/master/graph/badge.svg)](https://codecov.io/gh/metrue/fx)
[![Go Report Card](https://goreportcard.com/badge/github.com/metrue/fx?style=flat-square)](https://goreportcard.com/report/github.com/metrue/fx)
[![Go Doc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](http://godoc.org/github.com/metrue/fx)
![](https://img.shields.io/github/license/metrue/fx.svg)
![visitors](https://visitor-badge.glitch.me/badge?page_id=https://github.com/metrue/fx)
![liscense](https://img.shields.io/github/license/metrue/fx.svg)
[![Release](https://img.shields.io/github/release/metrue/fx.svg?style=flat-square)](https://github.com/metrue/fx/releases/latest)
## Table of Contents
- [Introduction](#introduction)
- [Installation](#installation)
- [Usage](#usage)
- [Manage Infrastructure](#manage-infrastructure)
- [Contribute](#contribute)
## Introduction
@@ -71,8 +69,6 @@ You can go the release page to [download](https://github.com/metrue/fx/releases)
## Usage
Make sure [Docker](https://docs.docker.com/engine/installation/) installed and running on your server first. then type `fx -h` on your terminal to check out basic help.
```
NAME:
fx - makes function as a service
@@ -80,17 +76,11 @@ NAME:
USAGE:
fx [global options] command [command options] [arguments...]
VERSION:
0.8.7
COMMANDS:
infra manage infrastructure
up deploy a function
down destroy a service
list, ls list deployed services
call run a function instantly
image manage image of service
doctor health check for fx
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
@@ -98,22 +88,40 @@ GLOBAL OPTIONS:
--version, -v print the version
```
### Deploy your function to Docker
### Deploy function
#### Local Docker environment
By default, function will be deployed on localhost make sure [Docker](https://docs.docker.com/engine/installation/) installed and running on your server first. then type `fx -h` on your terminal to check out basic help.
```
$ fx up --name hello-fx ./examples/functions/JavaScript/func.js
$ fx up --name hello ./examples/functions/JavaScript/func.js
+------------------------------------------------------------------+-----------+---------------+
| ID | NAME | ENDPOINT |
+------------------------------------------------------------------+-----------+---------------+
| 5b24d36608ee392c937a61a530805f74551ddec304aea3aca2ffa0fabcf98cf3 | /hello-fx | 0.0.0.0:58328 |
| 5b24d36608ee392c937a61a530805f74551ddec304aea3aca2ffa0fabcf98cf3 | /hello | 0.0.0.0:58328 |
+------------------------------------------------------------------+-----------+---------------+
```
### Deploy your function to Kubernetes
#### Remote host
Use `--host` to specify the target host for your function, or you can just set it to `FX_HOST` environment variable.
```shell
$ fx up --host roo@<your host> --name hello ./examples/functions/JavaScript/func.js
+------------------------------------------------------------------+-----------+---------------+
| ID | NAME | ENDPOINT |
+------------------------------------------------------------------+-----------+---------------+
| 5b24d36608ee392c937a61a530805f74551ddec304aea3aca2ffa0fabcf98cf3 | /hello | 0.0.0.0:58345 |
+------------------------------------------------------------------+-----------+---------------+
```
#### Kubernetes
```
$ KUBECONFIG=~/.kube/config ./build/fx up examples/functions/JavaScript/func.js --name hello-fx
$ FX_KUBECONF=~/.kube/config fx up examples/functions/JavaScript/func.js --name hello
+-------------------------------+------+----------------+
| ID | NAME | ENDPOINT |
@@ -122,7 +130,7 @@ $ KUBECONFIG=~/.kube/config ./build/fx up examples/functions/JavaScript/func.js
+------------------------+-------------+----------------+
```
### Test your service
### Test service
then you can test your service:
@@ -149,31 +157,6 @@ hello world
```
## Manage Infrastructure
**fx** is originally designed to turn a function into a runnable Docker container in a easiest way, on a host with Docker running, you can just deploy your function with `fx up` command, and now **fx** supports deploy function to be a service onto Kubernetes cluster infrasture, and we encourage you to do that other than on bare Docker environment, there are lots of advantage to run your function on Kubernetes like self-healing, load balancing, easy horizontal scaling, etc. It's pretty simple to deploy your function onto Kubernetes with **fx**, you just set KUBECONFIG in your enviroment.
By default. **fx** use localhost as target infrastructure to run your service, and you can also setup your remote virtual machines as **fx**'s infrastructure and deploy your functions onto it.
### `fx infra create`
You can create types (docker and k8s) of infrastructures for **fx** to deploy functions
```shell
$ fx infra create --name infra_us --type docker --host <user>@<ip> ## create docker type infrasture on <ip>
$ fx infra create --name infra_bj --type k8s --master <user>@<ip> --agents '<user1>@<ip1>,<user2>@<ip2>' ## create k8s type infrasture use <ip> as master node, and <ip1> and <ip2> as agents nodes
```
### `fx infra use`
To use a infrastructure, you can use `fx infra use` command to activate it.
```shell
fx infra use <infrastructure name>
```
and you can list your infrastructure with `fx infra list`
## Use Public Cloud Kubernetes Service as infrastructure to run your functions
* Azure Kubernetes Service (AKS)
@@ -198,7 +181,7 @@ aks-nodepool1-31718369-0 Ready agent 6m44s v1.12.8
Since AKS's config will be merged into `~/.kube/config` and set to be current context after you run `az aks get-credentials` command, so you can just set KUBECONFIG to default config also,
```shell
$ export KUBECONFIG=~/.kube/config # then fx will take the config to deloy function
$ export FX_KUBECONF=~/.kube/config # then fx will take the config to deloy function
```
But we would suggest you run `kubectl config current-context` to check if the current context is what you want.
@@ -224,7 +207,7 @@ $ kubectl config current-context
Then you can deploy your function onto GKE cluster with,
```shell
$ KUBECONFIG=~/.kube/config fx up examples/functions/JavaScript/func.js --name hellojs
$ FX_KUBECONF=~/.kube/config fx up examples/functions/JavaScript/func.js --name hellojs
```
* Setup your own Kubernetes cluster
@@ -233,31 +216,6 @@ $ KUBECONFIG=~/.kube/config fx up examples/functions/JavaScript/func.js --name h
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'
```
## Contribute
fx uses [Project](https://github.com/metrue/fx/projects/4) to manage the development.
#### Prerequisites
Docker: make sure [Docker](https://docs.docker.com/engine/installation/) installed and running on your server.
<a name="buildtest"></a>
#### Build & Test
```
$ git clone https://github.com/metrue/fx
$ cd fx
$ make build
```
Then you can build and test:
```
$ make build
$ ./build/fx -h
```
## Contributors

View File

@@ -1,4 +1,4 @@
FROM node:latest
FROM node:alpine
COPY . .
RUN npm install

View File

@@ -12,15 +12,588 @@
"vary": "^1.1.2"
}
},
"ajv": {
"version": "6.12.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
"integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"asn1": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
"requires": {
"safer-buffer": "~2.1.0"
}
},
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
},
"aws4": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
"integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug=="
},
"basic-auth": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
"integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
"requires": {
"safe-buffer": "5.1.2"
}
},
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
"requires": {
"tweetnacl": "^0.14.3"
}
},
"bintrees": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz",
"integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ="
},
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"cookies": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz",
"integrity": "sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==",
"requires": {
"depd": "~2.0.0",
"keygrip": "~1.1.0"
}
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"dashdash": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
"requires": {
"assert-plus": "^1.0.0"
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"requires": {
"ms": "^2.1.1"
}
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
},
"destroy": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
"requires": {
"jsbn": "~0.1.0",
"safer-buffer": "^2.1.0"
}
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
},
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
},
"etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"express-to-koa": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/express-to-koa/-/express-to-koa-2.0.0.tgz",
"integrity": "sha512-71zECby9NZHFGQ+kD+cJ5VaNUdCUw3oXkSC6PCmKxxfyVA11mVQCfwQqb7VjBmQbIJ2WNeiAeTOj7M5EqrMlOQ=="
},
"extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
},
"extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
},
"fast-deep-equal": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
"integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA=="
},
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
},
"forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
},
"form-data": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.6",
"mime-types": "^2.1.12"
}
},
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
},
"getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
"requires": {
"assert-plus": "^1.0.0"
}
},
"har-schema": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
},
"har-validator": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
"requires": {
"ajv": "^6.5.5",
"har-schema": "^2.0.0"
}
},
"http-errors": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
"integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.4",
"setprototypeof": "1.1.1",
"statuses": ">= 1.5.0 < 2",
"toidentifier": "1.0.0"
},
"dependencies": {
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
}
}
},
"http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
"requires": {
"assert-plus": "^1.0.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"is-typedarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
"isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
"jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
},
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
},
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
"json-schema": "0.2.3",
"verror": "1.10.0"
}
},
"keygrip": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz",
"integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==",
"requires": {
"tsscmp": "1.0.6"
}
},
"mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
},
"mime-db": {
"version": "1.44.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
"integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
},
"mime-types": {
"version": "2.1.27",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
"integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
"requires": {
"mime-db": "1.44.0"
}
},
"moment": {
"version": "2.26.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz",
"integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw=="
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node-fetch": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
},
"oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
"requires": {
"ee-first": "1.1.1"
}
},
"path-to-regexp": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.1.0.tgz",
"integrity": "sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw=="
},
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"prom-client": {
"version": "11.5.3",
"resolved": "https://registry.npmjs.org/prom-client/-/prom-client-11.5.3.tgz",
"integrity": "sha512-iz22FmTbtkyL2vt0MdDFY+kWof+S9UB/NACxSn2aJcewtw+EERsen0urSkZ2WrHseNdydsvcxCTAnPcSMZZv4Q==",
"requires": {
"tdigest": "^0.1.1"
}
},
"psl": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
},
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
"qs": {
"version": "6.9.4",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
"integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ=="
},
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
},
"request": {
"version": "2.88.2",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
"integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
"requires": {
"aws-sign2": "~0.7.0",
"aws4": "^1.8.0",
"caseless": "~0.12.0",
"combined-stream": "~1.0.6",
"extend": "~3.0.2",
"forever-agent": "~0.6.1",
"form-data": "~2.3.2",
"har-validator": "~5.1.3",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.19",
"oauth-sign": "~0.9.0",
"performance-now": "^2.1.0",
"qs": "~6.5.2",
"safe-buffer": "^5.1.2",
"tough-cookie": "~2.5.0",
"tunnel-agent": "^0.6.0",
"uuid": "^3.3.2"
},
"dependencies": {
"qs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
}
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"send": {
"version": "0.17.1",
"resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
"integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
"requires": {
"debug": "2.6.9",
"depd": "~1.1.2",
"destroy": "~1.0.4",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "~1.7.2",
"mime": "1.6.0",
"ms": "2.1.1",
"on-finished": "~2.3.0",
"range-parser": "~1.2.1",
"statuses": "~1.5.0"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
},
"dependencies": {
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
}
}
},
"setprototypeof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
},
"sshpk": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
"requires": {
"asn1": "~0.2.3",
"assert-plus": "^1.0.0",
"bcrypt-pbkdf": "^1.0.0",
"dashdash": "^1.12.0",
"ecc-jsbn": "~0.1.1",
"getpass": "^0.1.1",
"jsbn": "~0.1.0",
"safer-buffer": "^2.0.2",
"tweetnacl": "~0.14.0"
}
},
"statuses": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"swagger-stats": {
"version": "0.95.17",
"resolved": "https://registry.npmjs.org/swagger-stats/-/swagger-stats-0.95.17.tgz",
"integrity": "sha512-3p+sWzWpxWES5SAM6GeKa6jWrMvh5gmczKdscdmOl4e6n9e4gfz0HioBZQqRgdLKgRR2ZeSR4f7+e3mMjqcEhQ==",
"requires": {
"basic-auth": "^2.0.1",
"cookies": "^0.8.0",
"debug": "^4.1.1",
"moment": "^2.24.0",
"path-to-regexp": "^6.1.0",
"prom-client": "^11.5.3",
"qs": "^6.9.1",
"request": "^2.88.0",
"send": "^0.17.1",
"uuid": "^3.4.0"
}
},
"tdigest": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz",
"integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=",
"requires": {
"bintrees": "1.0.1"
}
},
"toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
},
"tough-cookie": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
"requires": {
"psl": "^1.1.28",
"punycode": "^2.1.1"
}
},
"tsscmp": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz",
"integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA=="
},
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
"requires": {
"safe-buffer": "^5.0.1"
}
},
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
"uri-js": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
"requires": {
"punycode": "^2.1.0"
}
},
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
},
"verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
"requires": {
"assert-plus": "^1.0.0",
"core-util-is": "1.0.2",
"extsprintf": "^1.2.0"
}
}
}
}

View File

@@ -11,10 +11,12 @@
"license": "ISC",
"dependencies": {
"@koa/cors": "^2.2.3",
"express-to-koa": "^2.0.0",
"get-port": "^3.2.0",
"is-generator-function": "^1.0.6",
"koa": "^2.3.0",
"koa-bodyparser": "^4.2.0",
"node-fetch": "^2.6.0"
"node-fetch": "^2.6.0",
"swagger-stats": "^0.95.17"
}
}

View File

@@ -1,3 +1,65 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "aead"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "aes"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "aes-gcm"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aead 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"aes 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ghash 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"subtle 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "aes-soft"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "aesni"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hermit-abi 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "base64"
version = "0.9.3"
@@ -9,11 +71,8 @@ dependencies = [
[[package]]
name = "base64"
version = "0.10.0"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
@@ -25,6 +84,38 @@ name = "bitflags"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "block-buffer"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "block-cipher-trait"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "block-padding"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "byte-tools"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.2.7"
@@ -39,11 +130,6 @@ dependencies = [
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cc"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.6"
@@ -59,13 +145,17 @@ dependencies = [
[[package]]
name = "cookie"
version = "0.11.0"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)",
"aes-gcm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hkdf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -76,6 +166,15 @@ dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crypto-mac"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "devise"
version = "0.2.0"
@@ -105,13 +204,26 @@ dependencies = [
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "digest"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fake-simd"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "filetime"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -122,7 +234,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -130,7 +242,7 @@ name = "fsevent-sys"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -152,6 +264,63 @@ name = "futures"
version = "0.1.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "generic-array"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "getrandom"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ghash"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"polyval 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "hermit-abi"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hkdf"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hmac"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "httparse"
version = "1.3.3"
@@ -198,7 +367,7 @@ dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -209,7 +378,7 @@ name = "inotify-sys"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -217,21 +386,10 @@ name = "iovec"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "isatty"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itoa"
version = "0.4.3"
@@ -263,7 +421,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.44"
version = "0.2.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -302,7 +460,7 @@ version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -324,7 +482,7 @@ dependencies = [
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -360,7 +518,7 @@ version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -375,7 +533,7 @@ dependencies = [
"fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -387,9 +545,14 @@ name = "num_cpus"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "opaque-debug"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "owning_ref"
version = "0.4.0"
@@ -412,7 +575,7 @@ name = "parking_lot_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -444,6 +607,25 @@ name = "percent-encoding"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "polyval"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"universal-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ppv-lite86"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro2"
version = "0.4.24"
@@ -467,11 +649,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ppv-lite86 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.2.2"
@@ -485,78 +688,84 @@ name = "rand_core"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ring"
version = "0.13.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
"untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rocket"
version = "0.4.0-rc.2"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"isatty 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pear 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket_codegen 0.4.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket_http 0.4.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket_codegen 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket_http 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"yansi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rocket_codegen"
version = "0.4.0-rc.2"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"devise 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket_http 0.4.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket_http 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"yansi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rocket_contrib"
version = "0.4.0-rc.2"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"notify 4.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket 0.4.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rocket_http"
version = "0.4.0-rc.2"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cookie 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"pear 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -566,8 +775,8 @@ dependencies = [
name = "rust"
version = "0.1.0"
dependencies = [
"rocket 0.4.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket_contrib 0.4.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket_contrib 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -642,6 +851,17 @@ dependencies = [
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "sha2"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "slab"
version = "0.4.1"
@@ -655,6 +875,11 @@ dependencies = [
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "smallvec"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "stable_deref_trait"
version = "1.1.1"
@@ -665,6 +890,16 @@ name = "state"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "subtle"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "subtle"
version = "2.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "0.15.22"
@@ -680,7 +915,7 @@ name = "time"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -738,6 +973,11 @@ name = "typeable"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "typenum"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicase"
version = "1.4.2"
@@ -764,6 +1004,15 @@ name = "unicode-xid"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "universal-hash"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"subtle 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unreachable"
version = "1.0.0"
@@ -772,11 +1021,6 @@ dependencies = [
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "untrusted"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "url"
version = "1.7.2"
@@ -792,6 +1036,11 @@ name = "version_check"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "version_check"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "void"
version = "1.0.2"
@@ -807,6 +1056,11 @@ dependencies = [
"winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.2.8"
@@ -863,27 +1117,51 @@ name = "yansi"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "zeroize"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "621fc7ecb8008f86d7fb9b95356cd692ce9514b80a86d85b397f32a22da7b9e2"
"checksum aead 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4cf01b9b56e767bb57b94ebf91a58b338002963785cdd7013e21c0d4679471e4"
"checksum aes 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "54eb1d8fe354e5fc611daf4f2ea97dd45a765f4f1e4512306ec183ae2e8f20c9"
"checksum aes-gcm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "834a6bda386024dbb7c8fc51322856c10ffe69559f972261c868485f5759c638"
"checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d"
"checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100"
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
"checksum base64 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "53d1ccbaf7d9ec9537465a97bf19edc1a4e158ecb49fc16178202238c569cc42"
"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
"checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774"
"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
"checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d"
"checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa"
"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1465f8134efa296b4c19db34d909637cb2bf0f7aaf21299e23e18fa29ac557cf"
"checksum cookie 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5795cda0897252e34380a27baf884c53aa7ad9990329cdad96d4c5d027015d44"
"checksum crossbeam-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c55913cc2799171a550e307918c0a360e8c16004820291bf3b638969b4a01816"
"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
"checksum devise 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e04ba2d03c5fa0d954c061fc8c9c288badadffc272ebb87679a89846de3ed3"
"checksum devise_codegen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "066ceb7928ca93a9bedc6d0e612a8a0424048b0ab1f75971b203d01420c055d7"
"checksum devise_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf41c59b22b5e3ec0ea55c7847e5f358d340f3a8d6d53a5cf4f1564967f96487"
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a2df5c1a8c4be27e7707789dc42ae65976e60b394afd293d1419ab915833e646"
"checksum fsevent 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "c4bbbf71584aeed076100b5665ac14e3d85eeb31fdbb45fbd41ef9a682b5ec05"
"checksum fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a772d36c338d07a032d5375a36f15f9a7043bf0cb8ce7cee658e037c6032874"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
"checksum ghash 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0930ed19a7184089ea46d2fedead2f6dc2b674c5db4276b7da336c7cd83252"
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
"checksum hermit-abi 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71"
"checksum hkdf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fa08a006102488bd9cd5b8013aabe84955cf5ae22e304c2caf655b633aefae3"
"checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695"
"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83"
"checksum hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)" = "df0caae6b71d266b91b4a83111a61d2b94ed2e2bea024c532b933dcff867e58c"
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
@@ -891,13 +1169,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718"
"checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0"
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
"checksum isatty 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e31a8281fc93ec9693494da65fbf28c0c2aa60a2eaec25dc58e2f31952e95edc"
"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
"checksum libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)" = "10923947f84a519a45c8fefb7dd1b3e8c08747993381adee176d7a82b4195311"
"checksum libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
@@ -910,23 +1187,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
"checksum notify 4.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "873ecfd8c174964ae30f401329d140142312c8e5590719cf1199d5f1717d8078"
"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5"
"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c"
"checksum pear 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c26d2b92e47063ffce70d3e3b1bd097af121a9e0db07ca38a6cc1cf0cc85ff25"
"checksum pear_codegen 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "336db4a192cc7f54efeb0c4e11a9245394824cc3bcbd37ba3ff51240c35d7a6e"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
"checksum polyval 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ec3341498978de3bfd12d1b22f1af1de22818f5473a11e8a6ef997989e3a212"
"checksum ppv-lite86 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09"
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
"checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
"checksum redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "679da7508e9a6390aeaf7fbd02a800fdc64b73fe2204dd2c8ae66d22d9d5ad5d"
"checksum ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a"
"checksum rocket 0.4.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eaa997ea8de9b14112aa38b2b6a0ecf3e651ff2c08d2fdf384fa765b5f9c2c98"
"checksum rocket_codegen 0.4.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fc68f90452ac88c6c1e02a922a0a23ef0ade08f9af899056d0c919b25fa7768c"
"checksum rocket_contrib 0.4.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2cc6a37cb7a6256efe6648f2d0ab9978c49ab883909ea4fabefb81d7c685d841"
"checksum rocket_http 0.4.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c7d555ce896830602aedf4bce2eec8d64713d45a2492c5a3625c3faa5f719b0f"
"checksum rocket 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6130967b369cfb8411b0b73e96fcba1229c32a9cc6f295d144f879bfced13c6e"
"checksum rocket_codegen 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "cb852e6da168fb948a8f2b798ba2e2f0e4fc860eae0efa9cf2bf0f5466bb0425"
"checksum rocket_contrib 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3946ca815127041d8f64455561031d058c22ae1b135251502c5ea523cf9e14b"
"checksum rocket_http 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1aff5a5480175f2f553a876b251e9350c74196128806d176da3a51c82aab5428"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"
"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9"
@@ -937,10 +1221,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef"
"checksum serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "225de307c6302bec3898c51ca302fc94a7a1697ef0845fcee6448f33c032249c"
"checksum serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "c37ccd6be3ed1fdf419ee848f7c758eb31b054d7cd3ae3600e3bae0adf569811"
"checksum sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
"checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d"
"checksum smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b73ea3738b47563803ef814925e69be00799a8c07420be8b996f8e98fb2336db"
"checksum smallvec 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4"
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
"checksum state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028"
"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
"checksum subtle 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "502d53007c02d7605a05df1c1a73ee436952781653da5d0bf57ad608f66932c1"
"checksum syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)" = "ae8b29eb5210bc5cf63ed6149cbf9adfc82ac0be023d8735c176ee74a2db4da7"
"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
"checksum tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c117b6cf86bb730aab4834f10df96e4dd586eff2c3c27d3781348da49e255bde"
@@ -949,16 +1237,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum toml 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "19782e145d5abefb03758958f06ea35f7b1d8421b534140e0238fd3d0bfd66e3"
"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
"checksum typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum universal-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df0c900f2f9b4116803415878ff48b63da9edb268668e08cf9292d7503114a01"
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f"
"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
"checksum version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1"
"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
@@ -968,3 +1259,4 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
"checksum yansi 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d60c3b48c9cdec42fb06b3b84b5b087405e1fa1c644a1af3930e4dfafe93de48"
"checksum yansi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71"
"checksum zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8"

View File

@@ -5,8 +5,8 @@ authors = ["FrontMage <xbgxwh@outlook.com>"]
edition = "2018"
[dependencies]
rocket = "0.4.0-rc.2"
rocket_contrib = "0.4.0-rc.2"
rocket = "0.4.5"
rocket_contrib = "0.4.5"
serde_json = "1.0"
serde_derive = "1.0.70"
serde = "1.0.70"

View File

@@ -1,7 +1,12 @@
FROM liuchong/rustup
WORKDIR /usr/src/myapp
FROM clux/muslrust:nightly AS builder
WORKDIR /build
COPY . .
RUN cp ./config ~/.cargo/ && rustup default nightly && cargo build
RUN ln -s /usr/bin/g++ /usr/bin/musl-g++ && cargo build --release
FROM scratch
WORKDIR /usr/src/myapp
COPY --from=builder /build/target/x86_64-unknown-linux-musl/release/rust /usr/src/myapp/
COPY ./Rocket.toml /usr/src/myapp/
EXPOSE 3000
CMD ["cargo", "run"]
ENV ROCKET_ENV=prod
CMD ["/usr/src/myapp/rust"]

View File

@@ -1,5 +1,23 @@
[development]
address = "localhost"
port = 3000
workers = 8
keep_alive = 5
log = "normal"
limits = { forms = 32768 }
[staging]
address = "0.0.0.0"
port = 3000
workers = 8
keep_alive = 5
log = "normal"
limits = { forms = 32768 }
[production]
address = "0.0.0.0"
port = 3000
workers = 8
keep_alive = 5
log = "critical"
limits = { forms = 32768 }

View File

@@ -4,7 +4,7 @@ pub mod fns {
pub result: i32,
}
#[derive(Deserialize)]
#[derive(Deserialize, FromForm)]
pub struct Request {
pub a: i32,
pub b: i32,

View File

@@ -10,13 +10,19 @@ extern crate serde_json;
mod fns;
use rocket::request::Form;
use rocket_contrib::json::Json;
#[get("/?<req..>")]
fn get(req: Form<fns::fns::Request>) -> Json<fns::fns::Response> {
Json(fns::fns::func(req.0))
}
#[post("/", format = "application/json", data = "<req>")]
fn index(req: Json<fns::fns::Request>) -> Json<fns::fns::Response> {
fn post(req: Json<fns::fns::Request>) -> Json<fns::fns::Response> {
Json(fns::fns::func(req.0))
}
fn main() {
rocket::ignite().mount("/", routes![index]).launch();
rocket::ignite().mount("/", routes![get, post]).launch();
}

44
bundle/bundle.go Normal file
View File

@@ -0,0 +1,44 @@
package bundle
import (
"fmt"
"github.com/metrue/fx/bundler"
"github.com/metrue/fx/bundler/d"
golang "github.com/metrue/fx/bundler/go"
"github.com/metrue/fx/bundler/java"
"github.com/metrue/fx/bundler/julia"
"github.com/metrue/fx/bundler/node"
"github.com/metrue/fx/bundler/perl"
"github.com/metrue/fx/bundler/python"
"github.com/metrue/fx/bundler/ruby"
"github.com/metrue/fx/bundler/rust"
)
// Bundle function to project
func Bundle(workdir string, language string, fn string, deps ...string) error {
var bundler bundler.Bundler
switch language {
case "d":
bundler = d.New()
case "node":
bundler = node.New()
case "go":
bundler = golang.New()
case "java":
bundler = java.New()
case "julia":
bundler = julia.New()
case "perl":
bundler = perl.New()
case "python":
bundler = python.New()
case "ruby":
bundler = ruby.New()
case "rust":
bundler = rust.New()
default:
return fmt.Errorf("%s not suppported yet", language)
}
return bundler.Bundle(workdir, fn, deps...)
}

117
bundle/bundler_test.go Normal file
View File

@@ -0,0 +1,117 @@
package bundle
import (
"io/ioutil"
"os"
"testing"
)
func createFn(content string, t *testing.T) string {
fd, err := ioutil.TempFile("", "fx_func_*.js")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(fd.Name(), []byte(content), 0666)
if err != nil {
t.Fatal(err)
}
return fd.Name()
}
func TestBundle(t *testing.T) {
workdir, err := ioutil.TempDir("", "fx-test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(workdir)
cases := []struct {
workdir string
language string
fn string
deps []string
}{
{
workdir: workdir,
language: "d",
fn: `
module.exports = (ctx) => {
ctx.body = 'hello fx'
}
`,
},
{
workdir: workdir,
language: "go",
fn: `
module.exports = (ctx) => {
ctx.body = 'hello fx'
}
`,
},
{
workdir: workdir,
language: "java",
fn: `
module.exports = (ctx) => {
ctx.body = 'hello fx'
}
`,
},
{
workdir: workdir,
language: "julia",
fn: `
module.exports = (ctx) => {
ctx.body = 'hello fx'
}
`,
},
{
workdir: workdir,
language: "perl",
fn: `
module.exports = (ctx) => {
ctx.body = 'hello fx'
}
`,
},
{
workdir: workdir,
language: "python",
fn: `
module.exports = (ctx) => {
ctx.body = 'hello fx'
}
`,
},
{
workdir: workdir,
language: "ruby",
fn: `
module.exports = (ctx) => {
ctx.body = 'hello fx'
}
`,
},
{
workdir: workdir,
language: "rust",
fn: `
module.exports = (ctx) => {
ctx.body = 'hello fx'
}
`,
},
}
for _, c := range cases {
fn := createFn(c.fn, t)
defer os.Remove(fn)
if err := Bundle(c.workdir, c.language, fn, c.deps...); err != nil {
t.Fatal(err)
}
}
}

63
bundler/README.md Normal file
View File

@@ -0,0 +1,63 @@
The only thing `fx` does is to make a single function to be an HTTP service, `fx` takes two steps to finish the process,
* Wraps the function into a web server project and make it be the handler function of the HTTP request.
* Builds the bundled web server to be Docker image, then run it as a Docker container and expose the service port.
`bundler` is the component responsible for step 1: wrap a single function (and its dependencies) into a web server. Take a Node web service as an example, the project looks like this,
```
helloworld
├── Dockerfile
├── app.js
└── fx.js
```
And the codes is pretty simple,
**app.js**
```javascript
const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const cors = require('@koa/cors');
const fx = require('./fx');
const app = new Koa();
app.use(cors({
origin: '*',
}));
app.use(bodyParser());
app.use(fx);
app.listen(3000);
```
**fx.js**
```javascript
module.exports = (ctx) => {
ctx.body = 'hello world'
}
```
**Dockerfile**
```dockerfile
FROM metrue/fx-node-base
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
```
You can see that it's a web service built with `Koa`, the request handler function defined in `fx.js` to response plain text `hello world`, so to make a general JavaScript/Node function to be a web service, we only have to put it into `fx.js` above, then build and run it with Docker and that's it.
To support different programming languages, `fx` needs to implement different `bundlers`, the reasons are,
* The way to set up a web service is different in different languages
* The way to manage dependency is different in different languages.
So there will be (are) different `bundlers` in `fx`.
```
go-bundler: based on Gin
ruby-bundler: based on Sinatra
node-bundler: based on Koa
python-bundler: based on flask
...
```

88
bundler/bundler.go Normal file
View File

@@ -0,0 +1,88 @@
package bundler
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/gobuffalo/packd"
"github.com/gobuffalo/packr/v2"
"github.com/metrue/fx/constants"
"github.com/metrue/fx/utils"
)
// Bundler defines interface
type Bundler interface {
Scaffold(output string) error
Bundle(output string, fn string, deps ...string) error
}
// IsHandler check if it's handle file
func IsHandler(name string, lang string) bool {
basename := filepath.Base(name)
nameWithoutExt := strings.TrimSuffix(basename, filepath.Ext(basename))
if constants.ExtLangMapping[filepath.Ext(basename)] != lang {
return false
}
return (nameWithoutExt == "fx" ||
// Fx is for Java
nameWithoutExt == "Fx" ||
// mod.rs is for Rust)
nameWithoutExt == "mod")
}
// Restore directory from packr box
func Restore(box *packr.Box, output string) error {
if err := box.Walk(func(name string, fd packd.File) error {
content, err := box.Find(name)
if err != nil {
return err
}
dest := filepath.Join(output, name)
if err := utils.EnsureFile(dest); err != nil {
return err
}
if err := ioutil.WriteFile(dest, content, 0600); err != nil {
return err
}
return nil
}); err != nil {
return err
}
return nil
}
// Bundle bundle a function
func Bundle(box *packr.Box, output string, language string, fn string, deps ...string) error {
if err := Restore(box, output); err != nil {
return err
}
if err := utils.Merge(output, deps...); err != nil {
return err
}
// Replace the default handler source file with given function source file
if err := filepath.Walk(output, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if IsHandler(path, language) {
if err := utils.CopyFile(fn, path); err != nil {
return err
}
}
return nil
}); err != nil {
return err
}
return nil
}

51
bundler/bundler_test.go Normal file
View File

@@ -0,0 +1,51 @@
package bundler
import (
"io/ioutil"
"log"
"os"
"testing"
"github.com/gobuffalo/packr/v2"
)
func TestBundler(t *testing.T) {
t.Run("Restore", func(t *testing.T) {
box := packr.New("", "./node/assets")
outputDir, err := ioutil.TempDir("", "fx_koa")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(outputDir)
if err := Restore(box, outputDir); err != nil {
t.Fatal(err)
}
})
t.Run("Bundle", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.js")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content := `
module.exports = (ctx) => {
ctx.body = 'hello fx'
}`
if err = ioutil.WriteFile(fd.Name(), []byte(content), 0666); err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_koa")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
box := packr.New("", "./node/assets")
if err := Bundle(box, outputDir, "node", fd.Name()); err != nil {
t.Fatal(err)
}
})
}

8
bundler/d/d-packr.go Normal file
View File

@@ -0,0 +1,8 @@
// +build !skippackr
// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT.
// You can use the "packr clean" command to clean up this,
// and any other packr generated files.
package d
import _ "github.com/metrue/fx/packrd"

32
bundler/d/d.go Normal file
View File

@@ -0,0 +1,32 @@
package d
import (
"github.com/gobuffalo/packr/v2"
"github.com/metrue/fx/bundler"
)
// D defines d bundler
type D struct {
assets *packr.Box
}
// New a koa bundler
func New() *D {
return &D{
assets: packr.New("d", "./assets"),
}
}
// Scaffold a koa app
func (d *D) Scaffold(output string) error {
return bundler.Restore(d.assets, output)
}
// Bundle a function into a koa project
func (d *D) Bundle(output string, fn string, deps ...string) error {
return bundler.Bundle(d.assets, output, "d", fn, deps...)
}
var (
_ bundler.Bundler = &D{}
)

32
bundler/go/go.go Normal file
View File

@@ -0,0 +1,32 @@
package golang
import (
"github.com/gobuffalo/packr/v2"
"github.com/metrue/fx/bundler"
)
// Gin defines javascript bundler
type Gin struct {
assets *packr.Box
}
// New a koa bundler
func New() *Gin {
return &Gin{
assets: packr.New("go", "./assets"),
}
}
// Scaffold a koa app
func (g *Gin) Scaffold(output string) error {
return bundler.Restore(g.assets, output)
}
// Bundle a function into a koa project
func (g *Gin) Bundle(output string, fn string, deps ...string) error {
return bundler.Bundle(g.assets, output, "go", fn, deps...)
}
var (
_ bundler.Bundler = &Gin{}
)

143
bundler/go/go_test.go Normal file
View File

@@ -0,0 +1,143 @@
package golang
import (
"io/ioutil"
"log"
"os"
"reflect"
"testing"
"github.com/metrue/fx/utils"
)
func TestKoaBundler(t *testing.T) {
t.Run("Scaffold", func(t *testing.T) {
outputDir, err := ioutil.TempDir("", "fx_koa")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
koa := New()
if err := koa.Scaffold(outputDir); err != nil {
t.Fatal(err)
}
diff, _, _, err := utils.Diff(outputDir, "./assets")
if err != nil {
t.Fatal(err)
}
if diff {
t.Fatalf("%s is not equal with %s", outputDir, "./assets")
}
})
t.Run("BundleSingleFunc", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.js")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content := `
module.exports = (ctx) => {
ctx.body = 'hello fx'
}`
err = ioutil.WriteFile(fd.Name(), []byte(content), 0666)
if err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_koa")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
koa := New()
if err := koa.Bundle(outputDir, fd.Name()); err != nil {
t.Fatal(err)
}
diff, pre, cur, err := utils.Diff("./assets", outputDir)
if err != nil {
t.Fatal(err)
}
if !diff {
t.Fatalf("handle functino should be changed")
}
if !reflect.DeepEqual(cur, []byte(content)) {
t.Fatalf("it should be %s but got %s", content, cur)
}
preHandleFunc, err := ioutil.ReadFile("./assets/fx.go")
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(pre, preHandleFunc) {
{
}
t.Fatalf("it should get %s but got %s", preHandleFunc, pre)
}
})
t.Run("BundleFuncAndDeps", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.js")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content, err := ioutil.ReadFile("./assets/fx.go")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(fd.Name(), content, 0666)
if err != nil {
t.Fatal(err)
}
addFunc := `
module.exports = (a, b) => a+b
`
addFd, err := ioutil.TempFile("", "fx_add_func_*.js")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(addFd.Name(), []byte(addFunc), 0644)
if err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_koa")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
koa := New()
if err := koa.Bundle(outputDir, fd.Name(), addFd.Name()); err != nil {
t.Fatal(err)
}
diff, pre, cur, err := utils.Diff("./assets", outputDir)
if err != nil {
t.Fatal(err)
}
if !diff {
t.Fatalf("handle functino should be changed")
}
if !reflect.DeepEqual(cur, []byte(addFunc)) {
t.Fatalf("it should be %s but got %s", content, cur)
}
if pre != nil {
t.Fatal(pre)
}
})
}

View File

@@ -0,0 +1,8 @@
// +build !skippackr
// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT.
// You can use the "packr clean" command to clean up this,
// and any other packr generated files.
package golang
import _ "github.com/metrue/fx/packrd"

View File

@@ -0,0 +1,8 @@
// +build !skippackr
// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT.
// You can use the "packr clean" command to clean up this,
// and any other packr generated files.
package java
import _ "github.com/metrue/fx/packrd"

32
bundler/java/java.go Normal file
View File

@@ -0,0 +1,32 @@
package java
import (
"github.com/gobuffalo/packr/v2"
"github.com/metrue/fx/bundler"
)
// Java defines javascript bundler
type Java struct {
assets *packr.Box
}
// New a koa bundler
func New() *Java {
return &Java{
assets: packr.New("java", "./assets"),
}
}
// Scaffold a koa app
func (k *Java) Scaffold(output string) error {
return bundler.Restore(k.assets, output)
}
// Bundle a function into a koa project
func (k *Java) Bundle(output string, fn string, deps ...string) error {
return bundler.Bundle(k.assets, output, "java", fn, deps...)
}
var (
_ bundler.Bundler = &Java{}
)

155
bundler/java/java_test.go Normal file
View File

@@ -0,0 +1,155 @@
package java
import (
"io/ioutil"
"log"
"os"
"reflect"
"testing"
"github.com/metrue/fx/utils"
)
func TestJavaBundler(t *testing.T) {
t.Run("Scaffold", func(t *testing.T) {
outputDir, err := ioutil.TempDir("", "fx_java")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
java := New()
if err := java.Scaffold(outputDir); err != nil {
t.Fatal(err)
}
diff, _, _, err := utils.Diff(outputDir, "./assets")
if err != nil {
t.Fatal(err)
}
if diff {
t.Fatalf("%s is not equal with %s", outputDir, "./assets")
}
})
t.Run("BundleSingleFunc", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.java")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content := `package fx;
import io.javalin.Javalin;
import org.json.JSONObject;
public class app {
public static void main(String[] args) {
Javalin app = Javalin.start(3000);
Fx handler = new Fx();
app.post("/", ctx -> {
JSONObject obj = new JSONObject(ctx.body());
ctx.result(""+handler.handle(obj));
});
}
}
`
err = ioutil.WriteFile(fd.Name(), []byte(content), 0666)
if err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_java")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
java := New()
if err := java.Bundle(outputDir, fd.Name()); err != nil {
t.Fatal(err)
}
diff, pre, cur, err := utils.Diff("./assets", outputDir)
if err != nil {
t.Fatal(err)
}
if !diff {
t.Fatalf("handle functino should be changed")
}
if !reflect.DeepEqual(cur, []byte(content)) {
t.Fatalf("it should be %s but got %s", content, cur)
}
preHandleFunc, err := ioutil.ReadFile("./assets/src/main/java/fx/Fx.java")
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(pre, preHandleFunc) {
{
}
t.Fatalf("it should get %s but got %s", preHandleFunc, pre)
}
})
t.Run("BundleFuncAndDeps", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.js")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content, err := ioutil.ReadFile("./assets/src/main/java/fx/Fx.java")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(fd.Name(), content, 0666)
if err != nil {
t.Fatal(err)
}
addFunc := `
module.exports = (a, b) => a+b
`
addFd, err := ioutil.TempFile("", "fx_add_func_*.js")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(addFd.Name(), []byte(addFunc), 0644)
if err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_java")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
java := New()
if err := java.Bundle(outputDir, fd.Name(), addFd.Name()); err != nil {
t.Fatal(err)
}
diff, pre, cur, err := utils.Diff("./assets", outputDir)
if err != nil {
t.Fatal(err)
}
if !diff {
t.Fatalf("handle functino should be changed")
}
if !reflect.DeepEqual(cur, []byte(addFunc)) {
t.Fatalf("it should be %s but got %s", content, cur)
}
if pre != nil {
t.Fatal(pre)
}
})
}

View File

@@ -1,4 +1,3 @@
struct Input
a::Number
b::Number

View File

@@ -0,0 +1,8 @@
// +build !skippackr
// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT.
// You can use the "packr clean" command to clean up this,
// and any other packr generated files.
package julia
import _ "github.com/metrue/fx/packrd"

32
bundler/julia/julia.go Normal file
View File

@@ -0,0 +1,32 @@
package julia
import (
"github.com/gobuffalo/packr/v2"
"github.com/metrue/fx/bundler"
)
// Julia defines javascript bundler
type Julia struct {
assets *packr.Box
}
// New a koa bundler
func New() *Julia {
return &Julia{
assets: packr.New("julia", "./assets"),
}
}
// Scaffold a koa app
func (k *Julia) Scaffold(output string) error {
return bundler.Restore(k.assets, output)
}
// Bundle a function into a koa project
func (k *Julia) Bundle(output string, fn string, deps ...string) error {
return bundler.Bundle(k.assets, output, "julia", fn, deps...)
}
var (
_ bundler.Bundler = &Julia{}
)

148
bundler/julia/julia_test.go Normal file
View File

@@ -0,0 +1,148 @@
package julia
import (
"io/ioutil"
"log"
"os"
"reflect"
"testing"
"github.com/metrue/fx/utils"
)
func TestJuliaBundler(t *testing.T) {
t.Run("Scaffold", func(t *testing.T) {
outputDir, err := ioutil.TempDir("", "fx_julia")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
julia := New()
if err := julia.Scaffold(outputDir); err != nil {
t.Fatal(err)
}
diff, _, _, err := utils.Diff(outputDir, "./assets")
if err != nil {
t.Fatal(err)
}
if diff {
t.Fatalf("%s is not equal with %s", outputDir, "./assets")
}
})
t.Run("BundleSingleFunc", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.julia")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content := `struct Input
a::Number
b::Number
end
fx = function(input::Input)
return input.a + input.b
end
`
err = ioutil.WriteFile(fd.Name(), []byte(content), 0666)
if err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_julia")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
julia := New()
if err := julia.Bundle(outputDir, fd.Name()); err != nil {
t.Fatal(err)
}
diff, pre, cur, err := utils.Diff("./assets", outputDir)
if err != nil {
t.Fatal(err)
}
if !diff {
t.Fatalf("handle function should be changed")
}
if !reflect.DeepEqual(cur, []byte(content)) {
t.Fatalf("it should be %s but got %s", content, cur)
}
preHandleFunc, err := ioutil.ReadFile("./assets/fx.jl")
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(pre, preHandleFunc) {
{
}
t.Fatalf("it should get %s but got %s", preHandleFunc, pre)
}
})
t.Run("BundleFuncAndDeps", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.js")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content, err := ioutil.ReadFile("./assets/fx.jl")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(fd.Name(), content, 0666)
if err != nil {
t.Fatal(err)
}
addFunc := `
module.exports = (a, b) => a+b
`
addFd, err := ioutil.TempFile("", "fx_add_func_*.js")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(addFd.Name(), []byte(addFunc), 0644)
if err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_julia")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
julia := New()
if err := julia.Bundle(outputDir, fd.Name(), addFd.Name()); err != nil {
t.Fatal(err)
}
diff, pre, cur, err := utils.Diff("./assets", outputDir)
if err != nil {
t.Fatal(err)
}
if !diff {
t.Fatalf("handle functino should be changed")
}
if !reflect.DeepEqual(cur, []byte(addFunc)) {
t.Fatalf("it should be %s but got %s", content, cur)
}
if pre != nil {
t.Fatal(pre)
}
})
}

View File

@@ -1,9 +1,13 @@
const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const cors = require('@koa/cors');
const swStats = require('swagger-stats');
const e2k = require('express-to-koa');
const fx = require('./fx');
const app = new Koa();
app.use(e2k(swStats.getMiddleware({})));
app.use(cors({
origin: '*',
}));

View File

@@ -0,0 +1,8 @@
// +build !skippackr
// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT.
// You can use the "packr clean" command to clean up this,
// and any other packr generated files.
package node
import _ "github.com/metrue/fx/packrd"

34
bundler/node/node.go Normal file
View File

@@ -0,0 +1,34 @@
package node
import (
"github.com/gobuffalo/packr/v2"
"github.com/metrue/fx/bundler"
)
const language = "node"
// Node defines node bundler
type Node struct {
assets *packr.Box
}
// New a koa bundler
func New() *Node {
return &Node{
assets: packr.New("node", "./assets"),
}
}
// Scaffold a koa app
func (k *Node) Scaffold(output string) error {
return bundler.Restore(k.assets, output)
}
// Bundle a function into a koa project
func (k *Node) Bundle(output string, fn string, deps ...string) error {
return bundler.Bundle(k.assets, output, language, fn, deps...)
}
var (
_ bundler.Bundler = &Node{}
)

143
bundler/node/node_test.go Normal file
View File

@@ -0,0 +1,143 @@
package node
import (
"io/ioutil"
"log"
"os"
"reflect"
"testing"
"github.com/metrue/fx/utils"
)
func TestNodeBundler(t *testing.T) {
t.Run("Scaffold", func(t *testing.T) {
outputDir, err := ioutil.TempDir("", "fx_koa")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
koa := New()
if err := koa.Scaffold(outputDir); err != nil {
t.Fatal(err)
}
diff, _, _, err := utils.Diff(outputDir, "./assets")
if err != nil {
t.Fatal(err)
}
if diff {
t.Fatalf("%s is not equal with %s", outputDir, "./assets")
}
})
t.Run("BundleSingleFunc", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.js")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content := `
module.exports = (ctx) => {
ctx.body = 'hello fx'
}`
err = ioutil.WriteFile(fd.Name(), []byte(content), 0666)
if err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_koa")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
koa := New()
if err := koa.Bundle(outputDir, fd.Name()); err != nil {
t.Fatal(err)
}
diff, pre, cur, err := utils.Diff("./assets", outputDir)
if err != nil {
t.Fatal(err)
}
if !diff {
t.Fatalf("handle functino should be changed")
}
if !reflect.DeepEqual(cur, []byte(content)) {
t.Fatalf("it should be %s but got %s", content, cur)
}
preHandleFunc, err := ioutil.ReadFile("./assets/fx.js")
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(pre, preHandleFunc) {
{
}
t.Fatalf("it should get %s but got %s", preHandleFunc, pre)
}
})
t.Run("BundleFuncAndDeps", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.js")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content, err := ioutil.ReadFile("./assets/fx.js")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(fd.Name(), content, 0666)
if err != nil {
t.Fatal(err)
}
addFunc := `
module.exports = (a, b) => a+b
`
addFd, err := ioutil.TempFile("", "fx_add_func_*.js")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(addFd.Name(), []byte(addFunc), 0644)
if err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_koa")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
koa := New()
if err := koa.Bundle(outputDir, fd.Name(), addFd.Name()); err != nil {
t.Fatal(err)
}
diff, pre, cur, err := utils.Diff("./assets", outputDir)
if err != nil {
t.Fatal(err)
}
if !diff {
t.Fatalf("handle functino should be changed")
}
if !reflect.DeepEqual(cur, []byte(addFunc)) {
t.Fatalf("it should be %s but got %s", content, cur)
}
if pre != nil {
t.Fatal(pre)
}
})
}

View File

@@ -0,0 +1,8 @@
// +build !skippackr
// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT.
// You can use the "packr clean" command to clean up this,
// and any other packr generated files.
package perl
import _ "github.com/metrue/fx/packrd"

32
bundler/perl/perl.go Normal file
View File

@@ -0,0 +1,32 @@
package perl
import (
"github.com/gobuffalo/packr/v2"
"github.com/metrue/fx/bundler"
)
// Julia defines javascript bundler
type Julia struct {
assets *packr.Box
}
// New a koa bundler
func New() *Julia {
return &Julia{
assets: packr.New("perl", "./assets"),
}
}
// Scaffold a koa app
func (k *Julia) Scaffold(output string) error {
return bundler.Restore(k.assets, output)
}
// Bundle a function into a koa project
func (k *Julia) Bundle(output string, fn string, deps ...string) error {
return bundler.Bundle(k.assets, output, "perl", fn, deps...)
}
var (
_ bundler.Bundler = &Julia{}
)

148
bundler/perl/perl_test.go Normal file
View File

@@ -0,0 +1,148 @@
package perl
import (
"io/ioutil"
"log"
"os"
"reflect"
"testing"
"github.com/metrue/fx/utils"
)
func TestJuliaBundler(t *testing.T) {
t.Run("Scaffold", func(t *testing.T) {
outputDir, err := ioutil.TempDir("", "fx_julia")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
julia := New()
if err := julia.Scaffold(outputDir); err != nil {
t.Fatal(err)
}
diff, _, _, err := utils.Diff(outputDir, "./assets")
if err != nil {
t.Fatal(err)
}
if diff {
t.Fatalf("%s is not equal with %s", outputDir, "./assets")
}
})
t.Run("BundleSingleFunc", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.julia")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content := `struct Input
a::Number
b::Number
end
fx = function(input::Input)
return input.a + input.b
end
`
err = ioutil.WriteFile(fd.Name(), []byte(content), 0666)
if err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_julia")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
julia := New()
if err := julia.Bundle(outputDir, fd.Name()); err != nil {
t.Fatal(err)
}
diff, pre, cur, err := utils.Diff("./assets", outputDir)
if err != nil {
t.Fatal(err)
}
if !diff {
t.Fatalf("handle function should be changed")
}
if !reflect.DeepEqual(cur, []byte(content)) {
t.Fatalf("it should be %s but got %s", content, cur)
}
preHandleFunc, err := ioutil.ReadFile("./assets/fx.pl")
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(pre, preHandleFunc) {
{
}
t.Fatalf("it should get %s but got %s", preHandleFunc, pre)
}
})
t.Run("BundleFuncAndDeps", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.js")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content, err := ioutil.ReadFile("./assets/fx.pl")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(fd.Name(), content, 0666)
if err != nil {
t.Fatal(err)
}
addFunc := `
module.exports = (a, b) => a+b
`
addFd, err := ioutil.TempFile("", "fx_add_func_*.js")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(addFd.Name(), []byte(addFunc), 0644)
if err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_julia")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
julia := New()
if err := julia.Bundle(outputDir, fd.Name(), addFd.Name()); err != nil {
t.Fatal(err)
}
diff, pre, cur, err := utils.Diff("./assets", outputDir)
if err != nil {
t.Fatal(err)
}
if !diff {
t.Fatalf("handle functino should be changed")
}
if !reflect.DeepEqual(cur, []byte(addFunc)) {
t.Fatalf("it should be %s but got %s", content, cur)
}
if pre != nil {
t.Fatal(pre)
}
})
}

View File

@@ -0,0 +1,8 @@
// +build !skippackr
// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT.
// You can use the "packr clean" command to clean up this,
// and any other packr generated files.
package python
import _ "github.com/metrue/fx/packrd"

32
bundler/python/python.go Normal file
View File

@@ -0,0 +1,32 @@
package python
import (
"github.com/gobuffalo/packr/v2"
"github.com/metrue/fx/bundler"
)
// Julia defines javascript bundler
type Julia struct {
assets *packr.Box
}
// New a koa bundler
func New() *Julia {
return &Julia{
assets: packr.New("python", "./assets"),
}
}
// Scaffold a koa app
func (k *Julia) Scaffold(output string) error {
return bundler.Restore(k.assets, output)
}
// Bundle a function into a koa project
func (k *Julia) Bundle(output string, fn string, deps ...string) error {
return bundler.Bundle(k.assets, output, "python", fn, deps...)
}
var (
_ bundler.Bundler = &Julia{}
)

View File

@@ -0,0 +1,148 @@
package python
import (
"io/ioutil"
"log"
"os"
"reflect"
"testing"
"github.com/metrue/fx/utils"
)
func TestJuliaBundler(t *testing.T) {
t.Run("Scaffold", func(t *testing.T) {
outputDir, err := ioutil.TempDir("", "fx_julia")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
julia := New()
if err := julia.Scaffold(outputDir); err != nil {
t.Fatal(err)
}
diff, _, _, err := utils.Diff(outputDir, "./assets")
if err != nil {
t.Fatal(err)
}
if diff {
t.Fatalf("%s is not equal with %s", outputDir, "./assets")
}
})
t.Run("BundleSingleFunc", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.julia")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content := `struct Input
a::Number
b::Number
end
fx = function(input::Input)
return input.a + input.b
end
`
err = ioutil.WriteFile(fd.Name(), []byte(content), 0666)
if err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_julia")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
julia := New()
if err := julia.Bundle(outputDir, fd.Name()); err != nil {
t.Fatal(err)
}
diff, pre, cur, err := utils.Diff("./assets", outputDir)
if err != nil {
t.Fatal(err)
}
if !diff {
t.Fatalf("handle function should be changed")
}
if !reflect.DeepEqual(cur, []byte(content)) {
t.Fatalf("it should be %s but got %s", content, cur)
}
preHandleFunc, err := ioutil.ReadFile("./assets/fx.py")
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(pre, preHandleFunc) {
{
}
t.Fatalf("it should get %s but got %s", preHandleFunc, pre)
}
})
t.Run("BundleFuncAndDeps", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.js")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content, err := ioutil.ReadFile("./assets/fx.py")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(fd.Name(), content, 0666)
if err != nil {
t.Fatal(err)
}
addFunc := `
module.exports = (a, b) => a+b
`
addFd, err := ioutil.TempFile("", "fx_add_func_*.js")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(addFd.Name(), []byte(addFunc), 0644)
if err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_julia")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
julia := New()
if err := julia.Bundle(outputDir, fd.Name(), addFd.Name()); err != nil {
t.Fatal(err)
}
diff, pre, cur, err := utils.Diff("./assets", outputDir)
if err != nil {
t.Fatal(err)
}
if !diff {
t.Fatalf("handle functino should be changed")
}
if !reflect.DeepEqual(cur, []byte(addFunc)) {
t.Fatalf("it should be %s but got %s", content, cur)
}
if pre != nil {
t.Fatal(pre)
}
})
}

View File

@@ -0,0 +1,8 @@
// +build !skippackr
// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT.
// You can use the "packr clean" command to clean up this,
// and any other packr generated files.
package ruby
import _ "github.com/metrue/fx/packrd"

32
bundler/ruby/ruby.go Normal file
View File

@@ -0,0 +1,32 @@
package ruby
import (
"github.com/gobuffalo/packr/v2"
"github.com/metrue/fx/bundler"
)
// Julia defines javascript bundler
type Julia struct {
assets *packr.Box
}
// New a koa bundler
func New() *Julia {
return &Julia{
assets: packr.New("ruby", "./assets"),
}
}
// Scaffold a koa app
func (k *Julia) Scaffold(output string) error {
return bundler.Restore(k.assets, output)
}
// Bundle a function into a koa project
func (k *Julia) Bundle(output string, fn string, deps ...string) error {
return bundler.Bundle(k.assets, output, "ruby", fn, deps...)
}
var (
_ bundler.Bundler = &Julia{}
)

148
bundler/ruby/ruby_test.go Normal file
View File

@@ -0,0 +1,148 @@
package ruby
import (
"io/ioutil"
"log"
"os"
"reflect"
"testing"
"github.com/metrue/fx/utils"
)
func TestJuliaBundler(t *testing.T) {
t.Run("Scaffold", func(t *testing.T) {
outputDir, err := ioutil.TempDir("", "fx_julia")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
julia := New()
if err := julia.Scaffold(outputDir); err != nil {
t.Fatal(err)
}
diff, _, _, err := utils.Diff(outputDir, "./assets")
if err != nil {
t.Fatal(err)
}
if diff {
t.Fatalf("%s is not equal with %s", outputDir, "./assets")
}
})
t.Run("BundleSingleFunc", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.julia")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content := `struct Input
a::Number
b::Number
end
fx = function(input::Input)
return input.a + input.b
end
`
err = ioutil.WriteFile(fd.Name(), []byte(content), 0666)
if err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_julia")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
julia := New()
if err := julia.Bundle(outputDir, fd.Name()); err != nil {
t.Fatal(err)
}
diff, pre, cur, err := utils.Diff("./assets", outputDir)
if err != nil {
t.Fatal(err)
}
if !diff {
t.Fatalf("handle function should be changed")
}
if !reflect.DeepEqual(cur, []byte(content)) {
t.Fatalf("it should be %s but got %s", content, cur)
}
preHandleFunc, err := ioutil.ReadFile("./assets/fx.rb")
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(pre, preHandleFunc) {
{
}
t.Fatalf("it should get %s but got %s", preHandleFunc, pre)
}
})
t.Run("BundleFuncAndDeps", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.js")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content, err := ioutil.ReadFile("./assets/fx.rb")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(fd.Name(), content, 0666)
if err != nil {
t.Fatal(err)
}
addFunc := `
module.exports = (a, b) => a+b
`
addFd, err := ioutil.TempFile("", "fx_add_func_*.js")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(addFd.Name(), []byte(addFunc), 0644)
if err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_julia")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
julia := New()
if err := julia.Bundle(outputDir, fd.Name(), addFd.Name()); err != nil {
t.Fatal(err)
}
diff, pre, cur, err := utils.Diff("./assets", outputDir)
if err != nil {
t.Fatal(err)
}
if !diff {
t.Fatalf("handle functino should be changed")
}
if !reflect.DeepEqual(cur, []byte(addFunc)) {
t.Fatalf("it should be %s but got %s", content, cur)
}
if pre != nil {
t.Fatal(pre)
}
})
}

View File

@@ -0,0 +1,8 @@
// +build !skippackr
// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT.
// You can use the "packr clean" command to clean up this,
// and any other packr generated files.
package rust
import _ "github.com/metrue/fx/packrd"

32
bundler/rust/rust.go Normal file
View File

@@ -0,0 +1,32 @@
package rust
import (
"github.com/gobuffalo/packr/v2"
"github.com/metrue/fx/bundler"
)
// Rust defines javascript bundler
type Rust struct {
assets *packr.Box
}
// New a koa bundler
func New() *Rust {
return &Rust{
assets: packr.New("rust", "./assets"),
}
}
// Scaffold a koa app
func (k *Rust) Scaffold(output string) error {
return bundler.Restore(k.assets, output)
}
// Bundle a function into a koa project
func (k *Rust) Bundle(output string, fn string, deps ...string) error {
return bundler.Bundle(k.assets, output, "rust", fn, deps...)
}
var (
_ bundler.Bundler = &Rust{}
)

148
bundler/rust/rust_test.go Normal file
View File

@@ -0,0 +1,148 @@
package rust
import (
"io/ioutil"
"log"
"os"
"reflect"
"testing"
"github.com/metrue/fx/utils"
)
func TestRustBundler(t *testing.T) {
t.Run("Scaffold", func(t *testing.T) {
outputDir, err := ioutil.TempDir("", "fx_rust")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
rust := New()
if err := rust.Scaffold(outputDir); err != nil {
t.Fatal(err)
}
diff, _, _, err := utils.Diff(outputDir, "./assets")
if err != nil {
t.Fatal(err)
}
if diff {
t.Fatalf("%s is not equal with %s", outputDir, "./assets")
}
})
t.Run("BundleSingleFunc", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.rust")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content := `struct Input
a::Number
b::Number
end
fx = function(input::Input)
return input.a + input.b
end
`
err = ioutil.WriteFile(fd.Name(), []byte(content), 0666)
if err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_rust")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
rust := New()
if err := rust.Bundle(outputDir, fd.Name()); err != nil {
t.Fatal(err)
}
diff, pre, cur, err := utils.Diff("./assets", outputDir)
if err != nil {
t.Fatal(err)
}
if !diff {
t.Fatalf("handle function should be changed")
}
if !reflect.DeepEqual(cur, []byte(content)) {
t.Fatalf("it should be %s but got %s", content, cur)
}
preHandleFunc, err := ioutil.ReadFile("./assets/src/fns/mod.rs")
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(pre, preHandleFunc) {
{
}
t.Fatalf("it should get %s but got %s", preHandleFunc, pre)
}
})
t.Run("BundleFuncAndDeps", func(t *testing.T) {
fd, err := ioutil.TempFile("", "fx_func_*.rs")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
content, err := ioutil.ReadFile("./assets/src/fns/mod.rs")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(fd.Name(), content, 0666)
if err != nil {
t.Fatal(err)
}
addFunc := `
module.exports = (a, b) => a+b
`
addFd, err := ioutil.TempFile("", "fx_add_func_*.rs")
if err != nil {
t.Fatal(err)
}
err = ioutil.WriteFile(addFd.Name(), []byte(addFunc), 0644)
if err != nil {
t.Fatal(err)
}
outputDir, err := ioutil.TempDir("", "fx_rust")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(outputDir)
rust := New()
if err := rust.Bundle(outputDir, fd.Name(), addFd.Name()); err != nil {
t.Fatal(err)
}
diff, pre, cur, err := utils.Diff("./assets", outputDir)
if err != nil {
t.Fatal(err)
}
if !diff {
t.Fatalf("handle functino should be changed")
}
if !reflect.DeepEqual(cur, []byte(addFunc)) {
t.Fatalf("it should be %s but got %s", content, cur)
}
if pre != nil {
t.Fatal(pre)
}
})
}

View File

@@ -1,207 +0,0 @@
package config
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"os/user"
"path"
"path/filepath"
dockerInfra "github.com/metrue/fx/infra/docker"
"github.com/metrue/fx/types"
"github.com/metrue/fx/utils"
"github.com/mitchellh/go-homedir"
)
// Configer manage fx config
type Configer interface {
GetCurrentCloud() ([]byte, error)
GetCurrentCloudType() (string, error)
GetKubeConfig() (string, error)
UseCloud(name string) error
View() ([]byte, error)
AddCloud(name string, meta []byte) error
Dir() (string, error)
}
// Config config of fx
type Config struct {
configFile string
container *Container
}
const defaultFxConfig = "~/.fx/config.yml"
// LoadDefault load default config
func LoadDefault() (*Config, error) {
configFile, err := homedir.Expand(defaultFxConfig)
if err != nil {
return nil, err
}
if os.Getenv("FX_CONFIG") != "" {
configFile = os.Getenv("FX_CONFIG")
}
if _, err := os.Stat(configFile); os.IsNotExist(err) {
if err := utils.EnsureFile(configFile); err != nil {
return nil, err
}
}
return load(configFile)
}
func load(configFile string) (*Config, error) {
container, err := CreateContainer(configFile)
if err != nil {
return nil, err
}
config := &Config{
configFile: configFile,
container: container,
}
if container.get("clouds") == nil {
if err := config.writeDefaultConfig(); err != nil {
return nil, err
}
}
return config, nil
}
// Load config
func Load(configFile string) (*Config, error) {
if configFile == "" {
return nil, fmt.Errorf("invalid config file")
}
if _, err := os.Stat(configFile); os.IsNotExist(err) {
if err := utils.EnsureFile(configFile); err != nil {
return nil, err
}
}
return load(configFile)
}
// AddCloud add k8s cloud
func (c *Config) AddCloud(name string, meta []byte) error {
var cloudMeta map[string]interface{}
if err := json.Unmarshal(meta, &cloudMeta); err != nil {
return err
}
cloudType, ok := cloudMeta["type"].(string)
if !ok || cloudType == "" {
return fmt.Errorf("unknown cloud type")
}
if cloudType == types.CloudTypeK8S {
dir := path.Dir(c.configFile)
kubecfg := path.Join(dir, name+".kubeconfig")
if err := utils.EnsureFile(kubecfg); err != nil {
return err
}
config, ok := cloudMeta["config"].(string)
if !ok {
return fmt.Errorf("invalid k8s config")
}
if err := ioutil.WriteFile(kubecfg, []byte(config), 0666); err != nil {
return err
}
}
if err := c.container.set("clouds."+name, cloudMeta); err != nil {
return err
}
return nil
}
// UseCloud set cloud instance with name as current context
func (c *Config) UseCloud(name string) error {
if name == "" {
return fmt.Errorf("could not use empty name")
}
if c.container.get("clouds."+name) == nil {
return fmt.Errorf("no such cloud with name: %s", name)
}
return c.container.set("current_cloud", name)
}
// View view current config
func (c *Config) View() ([]byte, error) {
return ioutil.ReadFile(c.configFile)
}
// GetCurrentCloud get current using cloud's meta
func (c *Config) GetCurrentCloud() ([]byte, error) {
name, ok := c.container.get("current_cloud").(string)
if !ok {
return nil, fmt.Errorf("no active cloud")
}
meta := c.container.get("clouds." + name)
if meta == nil {
return nil, fmt.Errorf("invalid config")
}
return json.Marshal(meta)
}
// GetCurrentCloudType get current cloud type
func (c *Config) GetCurrentCloudType() (string, error) {
name, ok := c.container.get("current_cloud").(string)
if !ok {
return "", fmt.Errorf("no active cloud")
}
return c.container.get("clouds." + name + ".type").(string), nil
}
// GetKubeConfig get kubeconfig
func (c *Config) GetKubeConfig() (string, error) {
name, ok := c.container.get("current_cloud").(string)
if !ok {
return "", fmt.Errorf("no active cloud")
}
dir := path.Dir(c.configFile)
kubecfg := path.Join(dir, name+".kubeconfig")
return kubecfg, nil
}
func (c *Config) writeDefaultConfig() error {
me, err := user.Current()
if err != nil {
return err
}
defaultCloud := &dockerInfra.Cloud{
IP: "127.0.0.1",
User: me.Username,
Name: "default",
Type: types.CloudTypeDocker,
}
meta, err := defaultCloud.Dump()
if err != nil {
return err
}
if err := c.container.set("clouds", map[string]interface{}{}); err != nil {
return err
}
if err := c.AddCloud("default", meta); err != nil {
return err
}
return c.UseCloud("default")
}
// Dir get directory of config
func (c *Config) Dir() (string, error) {
p, err := filepath.Abs(c.configFile)
if err != nil {
return "", err
}
return path.Dir(p), nil
}
var (
_ Configer = &Config{}
)

View File

@@ -1,131 +0,0 @@
package config
import (
"encoding/json"
"fmt"
"os"
"os/user"
"path/filepath"
"reflect"
"testing"
k8sInfra "github.com/metrue/fx/infra/k8s"
"github.com/metrue/fx/types"
)
func TestConfig(t *testing.T) {
configPath := "./tmp/config.yml"
defer func() {
if err := os.RemoveAll("./tmp/config.yml"); err != nil {
t.Fatal(err)
}
}()
// default cloud
c, err := Load(configPath)
if err != nil {
t.Fatal(err)
}
defaultMeta, err := c.GetCurrentCloud()
if err != nil {
t.Fatal(err)
}
var cloudMeta map[string]string
if err := json.Unmarshal(defaultMeta, &cloudMeta); err != nil {
t.Fatal(err)
}
if cloudMeta["ip"] != "127.0.0.1" {
t.Fatalf("should get %s but got %s", "127.0.0.1", cloudMeta["ip"])
}
me, _ := user.Current()
if cloudMeta["user"] != me.Username {
t.Fatalf("should get %s but got %s", me.Username, cloudMeta["user"])
}
if cloudMeta["type"] != types.CloudTypeDocker {
t.Fatalf("should get %s but got %s", types.CloudTypeDocker, cloudMeta["type"])
}
if cloudMeta["name"] != "default" {
t.Fatalf("should get %s but got %s", "default", cloudMeta["name"])
}
n1, err := k8sInfra.CreateNode(
"1.1.1.1",
"user-1",
"k3s-master",
"master-node",
)
if err != nil {
t.Fatal(err)
}
n2, err := k8sInfra.CreateNode(
"1.1.1.1",
"user-1",
"k3s-agent",
"agent-node-1",
)
if err != nil {
t.Fatal(err)
}
kName := "k8s-1"
kubeconf := "./tmp/" + kName + "config.yml"
defer func() {
if err := os.RemoveAll(kubeconf); err != nil {
t.Fatal(err)
}
}()
// add k8s cloud
kCloud := k8sInfra.NewCloud(kubeconf, n1, n2)
kMeta, err := kCloud.Dump()
if err != nil {
t.Fatal(err)
}
if err := c.AddCloud(kName, kMeta); err != nil {
t.Fatal(err)
}
curMeta, err := c.GetCurrentCloud()
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(curMeta, defaultMeta) {
t.Fatalf("should get %v but got %v", defaultMeta, curMeta)
}
if err := c.UseCloud("cloud-not-existed"); err == nil {
t.Fatalf("should get error when there is not given cloud name")
}
if err := c.UseCloud(kName); err != nil {
t.Fatal(err)
}
curMeta, err = c.GetCurrentCloud()
if err != nil {
t.Fatal(err)
}
if reflect.DeepEqual(curMeta, kMeta) {
t.Fatalf("should get %v but got %v", kMeta, curMeta)
}
body, err := c.View()
if err != nil {
t.Fatal(err)
}
fmt.Println(string(body))
dir, err := c.Dir()
if err != nil {
t.Fatal(err)
}
here, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
if dir != filepath.Join(here, "./tmp") {
t.Fatalf("should get %s but got %s", "./tmp", dir)
}
}

View File

@@ -1,73 +0,0 @@
package config
import (
"fmt"
"path/filepath"
"strings"
"sync"
"github.com/metrue/fx/utils"
"github.com/spf13/viper"
)
// Container config container, wrap viper as a key-value store with lock
type Container struct {
mux sync.Mutex
store string
}
// CreateContainer new a container
func CreateContainer(storeFile string) (*Container, error) {
if err := utils.EnsureFile(storeFile); err != nil {
return nil, err
}
dir := filepath.Dir(storeFile)
ext := filepath.Ext(storeFile)
name := filepath.Base(storeFile)
viper.AddConfigPath(dir)
viper.SetConfigName(strings.Replace(name, ext, "", 1))
viper.SetConfigType(strings.Replace(ext, ".", "", 1))
if err := viper.ReadInConfig(); err != nil {
return nil, err
}
return &Container{
store: storeFile,
}, nil
}
func (c *Container) set(key string, value interface{}) error {
c.mux.Lock()
defer c.mux.Unlock()
if key == "" {
return fmt.Errorf("empty key not allowed")
}
keys := strings.Split(key, ".")
if len(keys) == 1 {
viper.Set(key, value)
} else {
prePath := keys[0]
for i := 1; i < len(keys)-2; i++ {
prePath += "." + keys[i]
}
if viper.Get(prePath) == nil {
return fmt.Errorf("%s not existed", prePath)
}
viper.Set(key, value)
}
// viper.Set(key, value)
if err := viper.WriteConfig(); err != nil {
return err
}
return nil
}
func (c *Container) get(key string) interface{} {
c.mux.Lock()
defer c.mux.Unlock()
return viper.Get(key)
}

View File

@@ -1,84 +0,0 @@
package config
import (
"os"
"testing"
)
func TestContainer(t *testing.T) {
configPath := "./tmp/container.yml"
defer func() {
if err := os.RemoveAll("./tmp/container.yml"); err != nil {
t.Fatal(err)
}
}()
c, err := CreateContainer(configPath)
if err != nil {
t.Fatal(err)
}
if err := c.set("", ""); err == nil {
t.Fatalf("should get error when key is empty")
}
if c.get("1") != nil {
t.Fatalf("should get %v but got %v", nil, c.get("key"))
}
// create
if err := c.set("1", "1"); err != nil {
t.Fatal(err)
}
// read
if c.get("1").(string) != "1" {
t.Fatalf("should get %s but got %s", "val-1", c.get("key"))
}
// invaliad set
if err := c.set("1.1", "1.1"); err != nil {
t.Fatal(err)
}
if c.get("1.1").(string) != "1.1" {
t.Fatalf("should get 1.1 but got %s", c.get("1.1"))
}
// update
if err := c.set("1", "11"); err != nil {
t.Fatal(err)
}
if c.get("1").(string) != "11" {
t.Fatalf("should get 11 but got %s", c.get("1").(string))
}
// nested set
if err := c.set("2.2.2.2", "2222"); err == nil {
t.Fatalf("should throw error since 2.2.2 not ready yet")
}
if err := c.set("2", map[string]interface{}{
"2": map[string]interface{}{
"2": "2",
},
}); err != nil {
t.Fatal(err)
}
if c.get("2.2.2").(string) != "2" {
t.Fatalf("should get 2 but got %s", c.get("2.2.2"))
}
if err := c.set("2.2.2.2", "2222"); err != nil {
t.Fatal(err)
}
if c.get("2.2.2.2").(string) != "2222" {
t.Fatalf("should get 2222 but got %s", c.get("2.2.2.2"))
}
if err := c.set("2.2.2.1", "1111"); err != nil {
t.Fatal(err)
}
if c.get("2.2.2.1").(string) != "1111" {
t.Fatalf("should get 1111 but got %s", c.get("2.2.2.1"))
}
}

View File

@@ -1,14 +0,0 @@
package config
import (
"os"
)
// DisableContainerAutoremove to tell if to run container with --rm
var DisableContainerAutoremove = false
func init() {
if os.Getenv("DISABLE_CONTAINER_AUTOREMOVE") == "true" {
DisableContainerAutoremove = true
}
}

View File

@@ -1,17 +0,0 @@
package config
import (
"os"
"testing"
)
var _ = func() (_ struct{}) {
os.Setenv("DISABLE_CONTAINER_AUTOREMOVE", "true")
return
}()
func TestEnvLoad(t *testing.T) {
if !DisableContainerAutoremove {
t.Fatalf("should be true after set")
}
}

15
constants/languages.go Normal file
View File

@@ -0,0 +1,15 @@
package constants
// ExtLangMapping file extension mapping with programming language
var ExtLangMapping = map[string]string{
".js": "node",
".go": "go",
".rb": "ruby",
".py": "python",
".php": "php",
".jl": "julia",
".java": "java",
".d": "d",
".rs": "rust",
".pl": "perl",
}

View File

@@ -18,12 +18,10 @@ import (
"github.com/apex/log"
dockerTypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
dockerTypesContainer "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/go-connections/nat"
"github.com/google/go-querystring/query"
"github.com/google/uuid"
fxConfig "github.com/metrue/fx/config"
containerruntimes "github.com/metrue/fx/container_runtimes"
"github.com/metrue/fx/types"
"github.com/metrue/fx/utils"
@@ -32,10 +30,32 @@ import (
// API interact with dockerd http api
type API struct {
host string
port string
endpoint string
version string
}
// New a API
func New(host string, port string) *API {
return &API{
host: host,
port: port,
}
}
// Initialize an API
func (api *API) Initialize() error {
addr := api.host + ":" + api.port
v, err := version(addr)
if err != nil {
return err
}
endpoint := fmt.Sprintf("http://%s:%s/v%s", api.host, api.port, v)
api.endpoint = endpoint
return nil
}
// Create a API
func Create(host string, port string) (*API, error) {
addr := host + ":" + port
@@ -134,7 +154,8 @@ func (api *API) post(path string, body []byte, expectStatus int, v interface{})
// Version get version of docker engine
func (api *API) Version(ctx context.Context) (string, error) {
return version(api.endpoint)
addr := api.host + ":" + api.port
return version(addr)
}
func version(endpoint string) (string, error) {
@@ -397,13 +418,13 @@ func (api *API) StartContainer(ctx context.Context, name string, image string, b
portSet[port] = struct{}{}
portMap[port] = bindings
}
config := &dockerTypesContainer.Config{
config := &container.Config{
Image: image,
ExposedPorts: portSet,
}
hostConfig := &dockerTypesContainer.HostConfig{
AutoRemove: !fxConfig.DisableContainerAutoremove,
hostConfig := &container.HostConfig{
AutoRemove: false,
PortBindings: portMap,
}
@@ -453,11 +474,82 @@ func (api *API) StartContainer(ctx context.Context, name string, image string, b
return errors.New(msg)
}
if _, err = api.inspect(createRes.ID); err != nil {
msg := fmt.Sprintf("inspect container %s error", name)
return errors.Wrap(err, msg)
// wait seconds for container starting
time.Sleep(3 * time.Second)
info, err := api.inspect(createRes.ID)
if err != nil {
return errors.Wrap(err, "failed to inspect container "+createRes.ID)
}
if !info.State.Running {
logs, err := api.logs(createRes.ID)
if err != nil {
return errors.Wrap(err, "could not get logs of container "+createRes.ID)
}
if err := api.RemoveContainer(ctx, createRes.ID); err != nil {
msg := fmt.Sprintf("remove container %s failed, and container started with logs: %s", createRes.ID, string(logs))
return errors.Wrap(err, msg)
}
return fmt.Errorf("container start failure: %s", logs)
}
return nil
}
func (api *API) logs(id string) ([]byte, error) {
query := url.Values{}
query.Set("stdout", "true")
query.Set("stderr", "true")
path := fmt.Sprintf("/containers/%s/logs?%s", id, query.Encode())
url := fmt.Sprintf("%s%s", api.endpoint, path)
request, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
client := &http.Client{Timeout: 20 * time.Second}
resp, err := client.Do(request)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode == 200 {
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return b, nil
}
return nil, fmt.Errorf("get logs of container %s failed: %d", id, resp.StatusCode)
}
// RemoveContainer remove a container
func (api *API) RemoveContainer(ctx context.Context, id string) error {
query := url.Values{}
query.Set("v", "true")
path := fmt.Sprintf("/containers/%s?%s", id, query.Encode())
url := fmt.Sprintf("%s%s", api.endpoint, path)
request, err := http.NewRequest("DELETE", url, nil)
if err != nil {
return err
}
client := &http.Client{Timeout: 20 * time.Second}
resp, err := client.Do(request)
if err != nil {
return err
}
defer resp.Body.Close()
output, err := ioutil.ReadAll(resp.Body)
if err != nil {
return errors.Wrap(err, "read response body of remove container request failed")
}
if resp.StatusCode != 204 {
return fmt.Errorf("could not remove container %s: %s", id, string(output))
}
return nil
}

View File

@@ -1,4 +1,4 @@
FROM node:latest
FROM node:alpine
COPY . .
RUN npm install

View File

@@ -18,7 +18,6 @@ import (
"github.com/docker/docker/client"
"github.com/docker/go-connections/nat"
"github.com/google/uuid"
fxConfig "github.com/metrue/fx/config"
containerruntimes "github.com/metrue/fx/container_runtimes"
"github.com/metrue/fx/types"
"github.com/metrue/fx/utils"
@@ -162,7 +161,7 @@ func (d *Docker) StartContainer(ctx context.Context, name string, image string,
}
hostConfig := &dockerTypesContainer.HostConfig{
AutoRemove: !fxConfig.DisableContainerAutoremove,
AutoRemove: false,
PortBindings: portMap,
}
resp, err := d.ContainerCreate(ctx, config, hostConfig, nil, name)
@@ -245,6 +244,11 @@ func (d *Docker) Version(ctx context.Context) (string, error) {
return ping.APIVersion, nil
}
// RemoveContainer remove container
func (d *Docker) RemoveContainer(ctx context.Context, id string) error {
panic("no implemented yet")
}
var (
_ containerruntimes.ContainerRuntime = &Docker{}
)

View File

@@ -0,0 +1,178 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: runtimes.go
// Package mock_containerruntimes is a generated GoMock package.
package mock_containerruntimes
import (
context "context"
gomock "github.com/golang/mock/gomock"
types "github.com/metrue/fx/types"
reflect "reflect"
)
// MockContainerRuntime is a mock of ContainerRuntime interface
type MockContainerRuntime struct {
ctrl *gomock.Controller
recorder *MockContainerRuntimeMockRecorder
}
// MockContainerRuntimeMockRecorder is the mock recorder for MockContainerRuntime
type MockContainerRuntimeMockRecorder struct {
mock *MockContainerRuntime
}
// NewMockContainerRuntime creates a new mock instance
func NewMockContainerRuntime(ctrl *gomock.Controller) *MockContainerRuntime {
mock := &MockContainerRuntime{ctrl: ctrl}
mock.recorder = &MockContainerRuntimeMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockContainerRuntime) EXPECT() *MockContainerRuntimeMockRecorder {
return m.recorder
}
// BuildImage mocks base method
func (m *MockContainerRuntime) BuildImage(ctx context.Context, workdir, name string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BuildImage", ctx, workdir, name)
ret0, _ := ret[0].(error)
return ret0
}
// BuildImage indicates an expected call of BuildImage
func (mr *MockContainerRuntimeMockRecorder) BuildImage(ctx, workdir, name interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildImage", reflect.TypeOf((*MockContainerRuntime)(nil).BuildImage), ctx, workdir, name)
}
// PushImage mocks base method
func (m *MockContainerRuntime) PushImage(ctx context.Context, name string) (string, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "PushImage", ctx, name)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// PushImage indicates an expected call of PushImage
func (mr *MockContainerRuntimeMockRecorder) PushImage(ctx, name interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PushImage", reflect.TypeOf((*MockContainerRuntime)(nil).PushImage), ctx, name)
}
// InspectImage mocks base method
func (m *MockContainerRuntime) InspectImage(ctx context.Context, name string, img interface{}) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "InspectImage", ctx, name, img)
ret0, _ := ret[0].(error)
return ret0
}
// InspectImage indicates an expected call of InspectImage
func (mr *MockContainerRuntimeMockRecorder) InspectImage(ctx, name, img interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InspectImage", reflect.TypeOf((*MockContainerRuntime)(nil).InspectImage), ctx, name, img)
}
// TagImage mocks base method
func (m *MockContainerRuntime) TagImage(ctx context.Context, name, tag string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "TagImage", ctx, name, tag)
ret0, _ := ret[0].(error)
return ret0
}
// TagImage indicates an expected call of TagImage
func (mr *MockContainerRuntimeMockRecorder) TagImage(ctx, name, tag interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TagImage", reflect.TypeOf((*MockContainerRuntime)(nil).TagImage), ctx, name, tag)
}
// StartContainer mocks base method
func (m *MockContainerRuntime) StartContainer(ctx context.Context, name, image string, bindings []types.PortBinding) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "StartContainer", ctx, name, image, bindings)
ret0, _ := ret[0].(error)
return ret0
}
// StartContainer indicates an expected call of StartContainer
func (mr *MockContainerRuntimeMockRecorder) StartContainer(ctx, name, image, bindings interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartContainer", reflect.TypeOf((*MockContainerRuntime)(nil).StartContainer), ctx, name, image, bindings)
}
// StopContainer mocks base method
func (m *MockContainerRuntime) StopContainer(ctx context.Context, name string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "StopContainer", ctx, name)
ret0, _ := ret[0].(error)
return ret0
}
// StopContainer indicates an expected call of StopContainer
func (mr *MockContainerRuntimeMockRecorder) StopContainer(ctx, name interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopContainer", reflect.TypeOf((*MockContainerRuntime)(nil).StopContainer), ctx, name)
}
// RemoveContainer mocks base method
func (m *MockContainerRuntime) RemoveContainer(ctx context.Context, name string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RemoveContainer", ctx, name)
ret0, _ := ret[0].(error)
return ret0
}
// RemoveContainer indicates an expected call of RemoveContainer
func (mr *MockContainerRuntimeMockRecorder) RemoveContainer(ctx, name interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveContainer", reflect.TypeOf((*MockContainerRuntime)(nil).RemoveContainer), ctx, name)
}
// InspectContainer mocks base method
func (m *MockContainerRuntime) InspectContainer(ctx context.Context, name string, container interface{}) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "InspectContainer", ctx, name, container)
ret0, _ := ret[0].(error)
return ret0
}
// InspectContainer indicates an expected call of InspectContainer
func (mr *MockContainerRuntimeMockRecorder) InspectContainer(ctx, name, container interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InspectContainer", reflect.TypeOf((*MockContainerRuntime)(nil).InspectContainer), ctx, name, container)
}
// ListContainer mocks base method
func (m *MockContainerRuntime) ListContainer(ctx context.Context, filter string) ([]types.Service, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListContainer", ctx, filter)
ret0, _ := ret[0].([]types.Service)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ListContainer indicates an expected call of ListContainer
func (mr *MockContainerRuntimeMockRecorder) ListContainer(ctx, filter interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListContainer", reflect.TypeOf((*MockContainerRuntime)(nil).ListContainer), ctx, filter)
}
// Version mocks base method
func (m *MockContainerRuntime) Version(ctx context.Context) (string, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Version", ctx)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Version indicates an expected call of Version
func (mr *MockContainerRuntimeMockRecorder) Version(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Version", reflect.TypeOf((*MockContainerRuntime)(nil).Version), ctx)
}

View File

@@ -14,6 +14,7 @@ type ContainerRuntime interface {
TagImage(ctx context.Context, name string, tag string) error
StartContainer(ctx context.Context, name string, image string, bindings []types.PortBinding) error
StopContainer(ctx context.Context, name string) error
RemoveContainer(ctx context.Context, name string) error
InspectContainer(ctx context.Context, name string, container interface{}) error
ListContainer(ctx context.Context, filter string) ([]types.Service, error)
Version(ctx context.Context) (string, error)

View File

@@ -52,6 +52,7 @@ func (ctx *Context) GetCliContext() *cli.Context {
// Set a value with name
func (ctx *Context) Set(name string, value interface{}) {
// nolint
newCtx := context.WithValue(ctx.Context, name, value)
ctx.Context = newCtx
}

View File

@@ -36,11 +36,26 @@ $ curl 127.0.0.1:2000
## Deploy a function onto remote host
* make sure your instance can be ssh login
* make sure you can ssh login to target host with root
Update `/etc/ssh/sshd_config` to allow login with root.
```
PermitRootLogin yes
```
Then restart sshd with,
```shell
$ sudo service sshd restart
```
* make sure your instance accept port 8866
[FYI](https://lightsail.aws.amazon.com/ls/docs/en_us/articles/understanding-firewall-and-port-mappings-in-amazon-lightsail)
then you can deploy function to remote host
```shell
DOCKER_REMOTE_HOST_ADDR=<your host> DOCKER_REMOTE_HOST_USER=<your user> DOCKER_REMOTE_HOST_PASSWORD=<your password> fx up -p 2000 test/functions/func.js
fx up --host root@<your host> test/functions/func.js
```

View File

@@ -6,48 +6,66 @@ import (
dockerTypes "github.com/docker/docker/api/types"
containerruntimes "github.com/metrue/fx/container_runtimes"
"github.com/metrue/fx/infra"
"github.com/metrue/fx/driver"
"github.com/metrue/fx/pkg/spinner"
"github.com/metrue/fx/types"
)
// Deployer manage container
type Deployer struct {
cli containerruntimes.ContainerRuntime
// Driver manage container
type Driver struct {
dockerClient containerruntimes.ContainerRuntime
}
// CreateClient create a docker instance
func CreateClient(client containerruntimes.ContainerRuntime) (d *Deployer, err error) {
return &Deployer{cli: client}, nil
// Options to initialize a fx docker driver
type Options struct {
DockerClient containerruntimes.ContainerRuntime
}
// New a fx docker driver
func New(options Options) *Driver {
return &Driver{
dockerClient: options.DockerClient,
}
}
// Ping check healty status of driver
func (d *Driver) Ping(ctx context.Context) error {
if _, err := d.dockerClient.Version(ctx); err != nil {
return err
}
return nil
}
// Deploy create a Docker container from given image, and bind the constants.FxContainerExposePort to given port
func (d *Deployer) Deploy(ctx context.Context, fn string, name string, image string, ports []types.PortBinding) (err error) {
func (d *Driver) Deploy(ctx context.Context, fn string, name string, image string, ports []types.PortBinding) (err error) {
spinner.Start("deploying " + name)
defer func() {
spinner.Stop("deploying "+name, err)
}()
return d.cli.StartContainer(ctx, name, image, ports)
return d.dockerClient.StartContainer(ctx, name, image, ports)
}
// Update a container
func (d *Deployer) Update(ctx context.Context, name string) error {
func (d *Driver) Update(ctx context.Context, name string) error {
return nil
}
// Destroy stop and remove container
func (d *Deployer) Destroy(ctx context.Context, name string) (err error) {
func (d *Driver) Destroy(ctx context.Context, name string) (err error) {
spinner.Start("destroying " + name)
defer func() {
spinner.Stop("destroying "+name, err)
}()
return d.cli.StopContainer(ctx, name)
if err := d.dockerClient.StopContainer(ctx, name); err != nil {
return err
}
return d.dockerClient.RemoveContainer(ctx, name)
}
// GetStatus get a service status
func (d *Deployer) GetStatus(ctx context.Context, name string) (types.Service, error) {
func (d *Driver) GetStatus(ctx context.Context, name string) (types.Service, error) {
var container dockerTypes.ContainerJSON
if err := d.cli.InspectContainer(ctx, name, &container); err != nil {
if err := d.dockerClient.InspectContainer(ctx, name, &container); err != nil {
return types.Service{}, err
}
@@ -55,6 +73,7 @@ func (d *Deployer) GetStatus(ctx context.Context, name string) (types.Service, e
ID: container.ID,
Name: container.Name,
}
for _, bindings := range container.NetworkSettings.Ports {
if len(bindings) > 0 {
binding := bindings[0]
@@ -76,26 +95,12 @@ func (d *Deployer) GetStatus(ctx context.Context, name string) (types.Service, e
return service, nil
}
// Ping check healty status of infra
func (d *Deployer) Ping(ctx context.Context) error {
if _, err := d.cli.Version(ctx); err != nil {
return err
}
return nil
}
// List services
func (d *Deployer) List(ctx context.Context, name string) (svcs []types.Service, err error) {
const task = "listing"
spinner.Start(task)
defer func() {
spinner.Stop(task, err)
}()
func (d *Driver) List(ctx context.Context, name string) (svcs []types.Service, err error) {
// FIXME support remote host
return d.cli.ListContainer(ctx, name)
return d.dockerClient.ListContainer(ctx, name)
}
var (
_ infra.Deployer = &Deployer{}
_ driver.Driver = &Driver{}
)

View File

@@ -0,0 +1,95 @@
package docker
import (
"context"
"errors"
"testing"
"github.com/golang/mock/gomock"
dockerMock "github.com/metrue/fx/container_runtimes/mocks"
"github.com/metrue/fx/types"
)
func TestDriverPing(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
dockerClient := dockerMock.NewMockContainerRuntime(ctrl)
n := New(Options{
DockerClient: dockerClient,
})
ctx := context.Background()
dockerClient.EXPECT().Version(ctx).Return("", nil)
if err := n.Ping(ctx); err != nil {
t.Fatal(err)
}
}
func TestDriverDeploy(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
dockerClient := dockerMock.NewMockContainerRuntime(ctrl)
n := New(Options{
DockerClient: dockerClient,
})
ctx := context.Background()
fn := "fn"
name := "name"
image := "image"
ports := []types.PortBinding{}
dockerClient.EXPECT().StartContainer(ctx, name, image, ports).Return(nil)
if err := n.Deploy(ctx, fn, name, image, ports); err != nil {
t.Fatal(err)
}
}
func TestDriverDestroy(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
dockerClient := dockerMock.NewMockContainerRuntime(ctrl)
n := New(Options{
DockerClient: dockerClient,
})
ctx := context.Background()
name := "name"
dockerClient.EXPECT().StopContainer(ctx, name).Return(nil)
dockerClient.EXPECT().RemoveContainer(ctx, name).Return(nil)
if err := n.Destroy(ctx, name); err != nil {
t.Fatal(err)
}
}
func TestDriverGetStatus(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
dockerClient := dockerMock.NewMockContainerRuntime(ctrl)
n := New(Options{
DockerClient: dockerClient,
})
ctx := context.Background()
name := "name"
err := errors.New("no such container")
dockerClient.EXPECT().InspectContainer(ctx, name, gomock.Any()).Return(err)
if _, err := n.GetStatus(ctx, name); err == nil {
t.Fatalf("should get error")
}
}
func TestList(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
dockerClient := dockerMock.NewMockContainerRuntime(ctrl)
n := New(Options{
DockerClient: dockerClient,
})
ctx := context.Background()
name := "name"
dockerClient.EXPECT().ListContainer(ctx, name).Return(nil, nil)
if _, err := n.List(ctx, name); err != nil {
t.Fatal(err)
}
}

View File

@@ -1,4 +1,4 @@
package infra
package driver
import (
"context"
@@ -6,17 +6,8 @@ import (
"github.com/metrue/fx/types"
)
// Clouder cloud interface
type Clouder interface {
Provision() error
GetConfig() (string, error)
GetType() string
Dump() ([]byte, error)
IsHealth() (bool, error)
}
// Deployer deploy interface
type Deployer interface {
// Driver fx function running driver
type Driver interface {
Deploy(ctx context.Context, fn string, name string, image string, bindings []types.PortBinding) error
Destroy(ctx context.Context, name string) error
Update(ctx context.Context, name string) error
@@ -24,8 +15,3 @@ type Deployer interface {
List(ctx context.Context, name string) ([]types.Service, error)
Ping(ctx context.Context) error
}
// Infra infrastructure provision interface
type Infra interface {
Deployer
}

Some files were not shown because too many files have changed in this diff Show More