support policies, closes #12
This commit is contained in:
parent
37093adeab
commit
7e44d75f68
|
@ -0,0 +1,18 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/go-multierror"
|
||||||
|
"within.website/olin/policy"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ValidatePolicy(pol policy.Policy) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if pol.RamPageLimit > 2048 {
|
||||||
|
err = multierror.Append(err, fmt.Errorf("ram page limit is %d, which is over the limit of 2048", pol.RamPageLimit))
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
|
@ -3,12 +3,13 @@ package internal
|
||||||
import "github.com/rogpeppe/go-internal/txtar"
|
import "github.com/rogpeppe/go-internal/txtar"
|
||||||
|
|
||||||
// Topic name for wasmcloud -> executor communication
|
// Topic name for wasmcloud -> executor communication
|
||||||
const TopicName = "wasmcloud-to-executor-09d7e475-71ac-4bdd-be37-050af7a81c58"
|
const TopicName = "exec"
|
||||||
|
|
||||||
type ExecRequest struct {
|
type ExecRequest struct {
|
||||||
WASMCID string `json:"wasmcid"`
|
WASMCID string `json:"wasmcid"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Data []byte `json:"data"`
|
Data []byte `json:"data"`
|
||||||
|
Policy []byte `json:"policy"`
|
||||||
ABI ABI `json:"abi"`
|
ABI ABI `json:"abi"`
|
||||||
Env map[string]string `json:"env"`
|
Env map[string]string `json:"env"`
|
||||||
UUID string `json:"uuid"`
|
UUID string `json:"uuid"`
|
||||||
|
|
|
@ -8,6 +8,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
WASM []byte `json:"wasm"`
|
WASM []byte `json:"wasm"`
|
||||||
ABI string `json:"abi"`
|
Policy []byte `json:"policy"`
|
||||||
|
ABI string `json:"abi"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"github.com/rogpeppe/go-internal/txtar"
|
"github.com/rogpeppe/go-internal/txtar"
|
||||||
"tulpa.dev/within/wasmcloud/cmd/internal"
|
"tulpa.dev/within/wasmcloud/cmd/internal"
|
||||||
"tulpa.dev/within/wasmcloud/executor"
|
"tulpa.dev/within/wasmcloud/executor"
|
||||||
|
"within.website/olin/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -136,8 +137,17 @@ func waitForNewWASM(ctx context.Context, wg *sync.WaitGroup, sh *shell.Shell, nc
|
||||||
LogSink: logBuf,
|
LogSink: logBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pol, err := policy.Parse(er.Name+".policy", er.Policy)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("can't get policy: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Policy = &pol
|
||||||
|
|
||||||
result, err := executor.Run(c)
|
result, err := executor.Run(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Fprintln(logBuf, "can't run binary:", err)
|
||||||
log.Printf("can't run binary: %v", err)
|
log.Printf("can't run binary: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,11 @@ import (
|
||||||
|
|
||||||
"github.com/google/subcommands"
|
"github.com/google/subcommands"
|
||||||
"tulpa.dev/within/wasmcloud/cmd/internal"
|
"tulpa.dev/within/wasmcloud/cmd/internal"
|
||||||
|
"within.website/olin/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
type handlerCreateCmd struct {
|
type handlerCreateCmd struct {
|
||||||
abi string
|
abi, policyFile string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handlerCreateCmd) Name() string { return "create" }
|
func (handlerCreateCmd) Name() string { return "create" }
|
||||||
|
@ -38,6 +39,7 @@ Flags:
|
||||||
|
|
||||||
func (h *handlerCreateCmd) SetFlags(fs *flag.FlagSet) {
|
func (h *handlerCreateCmd) SetFlags(fs *flag.FlagSet) {
|
||||||
fs.StringVar(&h.abi, "abi", "cwa", "WebAssembly ABI to use for the handler")
|
fs.StringVar(&h.abi, "abi", "cwa", "WebAssembly ABI to use for the handler")
|
||||||
|
fs.StringVar(&h.policyFile, "policy", "", "if set, use this policy file for the handler")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h handlerCreateCmd) Execute(ctx context.Context, fs *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
func (h handlerCreateCmd) Execute(ctx context.Context, fs *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
||||||
|
@ -57,6 +59,25 @@ func (h handlerCreateCmd) Execute(ctx context.Context, fs *flag.FlagSet, _ ...in
|
||||||
WASM: data,
|
WASM: data,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if h.policyFile != "" {
|
||||||
|
data, err := ioutil.ReadFile(h.policyFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pol, err := policy.Parse(h.policyFile, data)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = internal.ValidatePolicy(pol)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
hdlr.Policy = data
|
||||||
|
}
|
||||||
|
|
||||||
bodyData, _ := json.Marshal(hdlr)
|
bodyData, _ := json.Marshal(hdlr)
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, *apiServer+"/api/handler/create", bytes.NewBuffer(bodyData))
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, *apiServer+"/api/handler/create", bytes.NewBuffer(bodyData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -15,10 +15,11 @@ import (
|
||||||
|
|
||||||
"github.com/google/subcommands"
|
"github.com/google/subcommands"
|
||||||
"tulpa.dev/within/wasmcloud/cmd/internal"
|
"tulpa.dev/within/wasmcloud/cmd/internal"
|
||||||
|
"within.website/olin/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
type handlerUpdateCmd struct {
|
type handlerUpdateCmd struct {
|
||||||
abi string
|
abi, policyFile string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handlerUpdateCmd) Name() string { return "update" }
|
func (handlerUpdateCmd) Name() string { return "update" }
|
||||||
|
@ -36,6 +37,7 @@ Flags:
|
||||||
|
|
||||||
func (h *handlerUpdateCmd) SetFlags(fs *flag.FlagSet) {
|
func (h *handlerUpdateCmd) SetFlags(fs *flag.FlagSet) {
|
||||||
fs.StringVar(&h.abi, "abi", "cwa", "WebAssembly ABI to use for the handler")
|
fs.StringVar(&h.abi, "abi", "cwa", "WebAssembly ABI to use for the handler")
|
||||||
|
fs.StringVar(&h.policyFile, "policy", "", "if set, use this policy file for the handler")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h handlerUpdateCmd) Execute(ctx context.Context, fs *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
func (h handlerUpdateCmd) Execute(ctx context.Context, fs *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
||||||
|
@ -56,6 +58,25 @@ func (h handlerUpdateCmd) Execute(ctx context.Context, fs *flag.FlagSet, _ ...in
|
||||||
WASM: data,
|
WASM: data,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if h.policyFile != "" {
|
||||||
|
data, err := ioutil.ReadFile(h.policyFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pol, err := policy.Parse(h.policyFile, data)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = internal.ValidatePolicy(pol)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
hdlr.Policy = data
|
||||||
|
}
|
||||||
|
|
||||||
bodyData, _ := json.Marshal(hdlr)
|
bodyData, _ := json.Marshal(hdlr)
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, *apiServer+"/api/handler/update?name="+hname, bytes.NewBuffer(bodyData))
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, *apiServer+"/api/handler/update?name="+hname, bytes.NewBuffer(bodyData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -17,12 +17,12 @@ import (
|
||||||
"github.com/perlin-network/life/exec"
|
"github.com/perlin-network/life/exec"
|
||||||
"github.com/rogpeppe/go-internal/txtar"
|
"github.com/rogpeppe/go-internal/txtar"
|
||||||
"tulpa.dev/within/wasmcloud/executor"
|
"tulpa.dev/within/wasmcloud/executor"
|
||||||
|
"within.website/olin/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
type runCmd struct {
|
type runCmd struct {
|
||||||
funcName, abi string
|
funcName, abi string
|
||||||
gasLimit uint64
|
policyFile string
|
||||||
ramLimit int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (runCmd) Name() string { return "run" }
|
func (runCmd) Name() string { return "run" }
|
||||||
|
@ -33,7 +33,6 @@ func (runCmd) Usage() string {
|
||||||
return `wasmcloud run [options] <file.wasm>
|
return `wasmcloud run [options] <file.wasm>
|
||||||
|
|
||||||
$ wasmcloud run olinfetch.wasm
|
$ wasmcloud run olinfetch.wasm
|
||||||
$ wasmcloud run -abi dagger -func-name dagger_main hello_dagger.wasm
|
|
||||||
|
|
||||||
Run a given webassembly binary and return the output.
|
Run a given webassembly binary and return the output.
|
||||||
|
|
||||||
|
@ -47,8 +46,7 @@ Flags:
|
||||||
func (r *runCmd) SetFlags(fs *flag.FlagSet) {
|
func (r *runCmd) SetFlags(fs *flag.FlagSet) {
|
||||||
fs.StringVar(&r.funcName, "func-name", "_start", "entrypoint function to call")
|
fs.StringVar(&r.funcName, "func-name", "_start", "entrypoint function to call")
|
||||||
fs.StringVar(&r.abi, "abi", "cwa", "ABI to use")
|
fs.StringVar(&r.abi, "abi", "cwa", "ABI to use")
|
||||||
fs.Uint64Var(&r.gasLimit, "gas-limit", 1048576, "number of wasm instructions per execution")
|
fs.StringVar(&r.policyFile, "policy", "", "if set, the policy file to use")
|
||||||
fs.IntVar(&r.ramLimit, "ram-limit", 128, "number of wasm pages that can be used")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r runCmd) Execute(ctx context.Context, fs *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
func (r runCmd) Execute(ctx context.Context, fs *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
||||||
|
@ -86,9 +84,7 @@ func (r runCmd) Execute(ctx context.Context, fs *flag.FlagSet, _ ...interface{})
|
||||||
var stdin bytes.Buffer
|
var stdin bytes.Buffer
|
||||||
c := executor.Config{
|
c := executor.Config{
|
||||||
VMConfig: exec.VMConfig{
|
VMConfig: exec.VMConfig{
|
||||||
GasLimit: r.gasLimit,
|
|
||||||
ReturnOnGasLimitExceeded: true,
|
ReturnOnGasLimitExceeded: true,
|
||||||
MaxMemoryPages: r.ramLimit,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
Name: filepath.Base(fname),
|
Name: filepath.Base(fname),
|
||||||
|
@ -101,6 +97,22 @@ func (r runCmd) Execute(ctx context.Context, fs *flag.FlagSet, _ ...interface{})
|
||||||
LogSink: logBuf,
|
LogSink: logBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if r.policyFile != "" {
|
||||||
|
data, err := ioutil.ReadFile(r.policyFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pol, err := policy.Parse(r.policyFile, data)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.VMConfig.MaxMemoryPages = int(pol.RamPageLimit)
|
||||||
|
c.VMConfig.GasLimit = uint64(pol.GasLimit)
|
||||||
|
c.Policy = &pol
|
||||||
|
}
|
||||||
|
|
||||||
result, err := executor.Run(c)
|
result, err := executor.Run(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("can't run binary: %v", err)
|
log.Printf("can't run binary: %v", err)
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"within.website/ln"
|
"within.website/ln"
|
||||||
"within.website/ln/opname"
|
"within.website/ln/opname"
|
||||||
"within.website/olin/namegen"
|
"within.website/olin/namegen"
|
||||||
|
"within.website/olin/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
func deleteHandler(w http.ResponseWriter, r *http.Request, u *User) {
|
func deleteHandler(w http.ResponseWriter, r *http.Request, u *User) {
|
||||||
|
@ -72,6 +73,15 @@ func updateHandler(w http.ResponseWriter, r *http.Request, u *User) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(uHdlr.Policy) != 0 {
|
||||||
|
err = validatePolicy(name, uHdlr.Policy)
|
||||||
|
if err != nil {
|
||||||
|
ln.Error(ctx, err)
|
||||||
|
http.Error(w, "policy validation failure", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cid, err := uploadHandler(uHdlr)
|
cid, err := uploadHandler(uHdlr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ln.Error(ctx, err)
|
ln.Error(ctx, err)
|
||||||
|
@ -79,6 +89,7 @@ func updateHandler(w http.ResponseWriter, r *http.Request, u *User) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hdlr.Policy = uHdlr.Policy
|
||||||
hdlr.Path = cid
|
hdlr.Path = cid
|
||||||
if err := db.Save(&hdlr).Error; err != nil {
|
if err := db.Save(&hdlr).Error; err != nil {
|
||||||
ln.Error(ctx, err)
|
ln.Error(ctx, err)
|
||||||
|
@ -89,6 +100,15 @@ func updateHandler(w http.ResponseWriter, r *http.Request, u *User) {
|
||||||
json.NewEncoder(w).Encode(hdlr)
|
json.NewEncoder(w).Encode(hdlr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validatePolicy(name string, data []byte) error {
|
||||||
|
pol, err := policy.Parse(name+".policy", data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return internal.ValidatePolicy(pol)
|
||||||
|
}
|
||||||
|
|
||||||
func uploadHandler(hdlr internal.Handler) (string, error) {
|
func uploadHandler(hdlr internal.Handler) (string, error) {
|
||||||
sh := shell.NewShell(*ipfsURL)
|
sh := shell.NewShell(*ipfsURL)
|
||||||
|
|
||||||
|
@ -135,6 +155,19 @@ func createHandler(w http.ResponseWriter, r *http.Request, u *User) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n := namegen.Next()
|
||||||
|
|
||||||
|
if len(hdlr.Policy) == 0 {
|
||||||
|
hdlr.Policy = []byte(defaultPolicy)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = validatePolicy(n, hdlr.Policy)
|
||||||
|
if err != nil {
|
||||||
|
ln.Error(ctx, err)
|
||||||
|
http.Error(w, "policy validation failure", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
cid, err := uploadHandler(hdlr)
|
cid, err := uploadHandler(hdlr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ln.Error(ctx, err)
|
ln.Error(ctx, err)
|
||||||
|
@ -142,12 +175,12 @@ func createHandler(w http.ResponseWriter, r *http.Request, u *User) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
n := namegen.Next()
|
|
||||||
h := Handler{
|
h := Handler{
|
||||||
Name: n,
|
Name: n,
|
||||||
User: *u,
|
User: *u,
|
||||||
UserID: u.ID,
|
UserID: u.ID,
|
||||||
Path: cid,
|
Path: cid,
|
||||||
|
Policy: hdlr.Policy,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := db.Save(&h).Error; err != nil {
|
if err := db.Save(&h).Error; err != nil {
|
||||||
|
|
|
@ -23,7 +23,8 @@ func runHandler(ctx context.Context, hdlr Handler, timeout time.Duration, messag
|
||||||
"RUN_ID": execID,
|
"RUN_ID": execID,
|
||||||
"MAGIC_CONCH": "yes",
|
"MAGIC_CONCH": "yes",
|
||||||
},
|
},
|
||||||
UUID: execID,
|
UUID: execID,
|
||||||
|
Policy: hdlr.Policy,
|
||||||
}
|
}
|
||||||
|
|
||||||
encData, err := json.Marshal(er)
|
encData, err := json.Marshal(er)
|
||||||
|
|
|
@ -37,6 +37,7 @@ type Handler struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
Name string `gorm:"unique;not null"`
|
Name string `gorm:"unique;not null"`
|
||||||
Path string
|
Path string
|
||||||
|
Policy []byte
|
||||||
UserID uint `json:"-"`
|
UserID uint `json:"-"`
|
||||||
User User `json:"-"`
|
User User `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
const defaultPolicy = `## The default policy
|
||||||
|
|
||||||
|
allow (
|
||||||
|
^null://$
|
||||||
|
^random://$
|
||||||
|
^zero://$
|
||||||
|
^https://xena.greedo.xeserv.us/files/hello_olin.txt$
|
||||||
|
)
|
||||||
|
|
||||||
|
ram-page-limit 128
|
||||||
|
gas-limit 1048576
|
||||||
|
`
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/perlin-network/life/exec"
|
"github.com/perlin-network/life/exec"
|
||||||
"github.com/rogpeppe/go-internal/txtar"
|
"github.com/rogpeppe/go-internal/txtar"
|
||||||
"within.website/olin/abi/cwa"
|
"within.website/olin/abi/cwa"
|
||||||
|
"within.website/olin/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -24,6 +25,7 @@ var (
|
||||||
type Config struct {
|
type Config struct {
|
||||||
exec.VMConfig
|
exec.VMConfig
|
||||||
|
|
||||||
|
Policy *policy.Policy
|
||||||
Name string
|
Name string
|
||||||
FuncName string
|
FuncName string
|
||||||
Env map[string]string
|
Env map[string]string
|
||||||
|
@ -77,7 +79,8 @@ func Run(c Config) (*Result, error) {
|
||||||
p.Stdout = c.Stdout
|
p.Stdout = c.Stdout
|
||||||
p.Stderr = c.Stderr
|
p.Stderr = c.Stderr
|
||||||
p.Logger = log.New(io.MultiWriter(c.LogSink, os.Stdout), c.Name+" ", log.LstdFlags)
|
p.Logger = log.New(io.MultiWriter(c.LogSink, os.Stdout), c.Name+" ", log.LstdFlags)
|
||||||
p.HC.Transport = WasmcloudBrandingTransport(c.Name, p.HC.Transport)
|
p.HC.Transport = WasmcloudBrandingTransport(c.Name, http.DefaultTransport)
|
||||||
|
p.Policy = c.Policy
|
||||||
|
|
||||||
gp := &compiler.SimpleGasPolicy{GasPerInstruction: 1}
|
gp := &compiler.SimpleGasPolicy{GasPerInstruction: 1}
|
||||||
vm, err := exec.NewVirtualMachine(c.Binary, c.VMConfig, p, gp)
|
vm, err := exec.NewVirtualMachine(c.Binary, c.VMConfig, p, gp)
|
||||||
|
@ -92,9 +95,13 @@ func Run(c Config) (*Result, error) {
|
||||||
|
|
||||||
pagesBefore := len(vm.Memory) / 65536
|
pagesBefore := len(vm.Memory) / 65536
|
||||||
begin := time.Now()
|
begin := time.Now()
|
||||||
ret, err := vm.Run(main)
|
ret, err := vm.RunWithGasLimit(main, int(c.Policy.GasLimit))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
vm.PrintStackTrace()
|
||||||
|
return &Result{
|
||||||
|
Status: -2,
|
||||||
|
StartTime: begin,
|
||||||
|
}, err
|
||||||
}
|
}
|
||||||
dur := time.Since(begin)
|
dur := time.Since(begin)
|
||||||
|
|
||||||
|
|
3
go.mod
3
go.mod
|
@ -11,8 +11,10 @@ require (
|
||||||
github.com/google/uuid v1.1.1
|
github.com/google/uuid v1.1.1
|
||||||
github.com/gorilla/mux v1.7.3
|
github.com/gorilla/mux v1.7.3
|
||||||
github.com/gosuri/uitable v0.0.4
|
github.com/gosuri/uitable v0.0.4
|
||||||
|
github.com/hashicorp/go-multierror v1.0.0
|
||||||
github.com/ipfs/go-ipfs-api v0.0.2
|
github.com/ipfs/go-ipfs-api v0.0.2
|
||||||
github.com/jinzhu/gorm v1.9.11
|
github.com/jinzhu/gorm v1.9.11
|
||||||
|
github.com/kr/pretty v0.1.0
|
||||||
github.com/lib/pq v1.1.1
|
github.com/lib/pq v1.1.1
|
||||||
github.com/manifoldco/promptui v0.6.0
|
github.com/manifoldco/promptui v0.6.0
|
||||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible
|
github.com/mattn/go-sqlite3 v2.0.1+incompatible
|
||||||
|
@ -20,6 +22,7 @@ require (
|
||||||
github.com/nats-io/nats.go v1.9.1
|
github.com/nats-io/nats.go v1.9.1
|
||||||
github.com/perlin-network/life v0.0.0-20191203030451-05c0e0f7eaea
|
github.com/perlin-network/life v0.0.0-20191203030451-05c0e0f7eaea
|
||||||
github.com/rogpeppe/go-internal v1.5.0
|
github.com/rogpeppe/go-internal v1.5.0
|
||||||
|
github.com/rogpeppe/gohack v1.0.2 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392
|
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392
|
||||||
within.website/ln v0.7.0
|
within.website/ln v0.7.0
|
||||||
within.website/olin v0.4.1-0.20191214133128-bde4927fad6b
|
within.website/olin v0.4.1-0.20191214133128-bde4927fad6b
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -143,7 +143,9 @@ github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyF
|
||||||
github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU=
|
github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU=
|
||||||
github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc=
|
github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc=
|
||||||
github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48=
|
github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48=
|
||||||
|
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
|
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
||||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
@ -299,8 +301,11 @@ github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||||
|
github.com/rogpeppe/go-internal v1.0.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.5.0 h1:Usqs0/lDK/NqTkvrmKSwA/3XkZAs7ZAW/eLeQ2MVBTw=
|
github.com/rogpeppe/go-internal v1.5.0 h1:Usqs0/lDK/NqTkvrmKSwA/3XkZAs7ZAW/eLeQ2MVBTw=
|
||||||
github.com/rogpeppe/go-internal v1.5.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
github.com/rogpeppe/go-internal v1.5.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
|
github.com/rogpeppe/gohack v1.0.2 h1:lYiGLFzvZC3RvzeE4GoUV3nTecDxTpVusVsQY4nAXGc=
|
||||||
|
github.com/rogpeppe/gohack v1.0.2/go.mod h1:DE8wqaJRPvHU0fden5cSYy7ar2dTbbccPT/eeOYcbcE=
|
||||||
github.com/sendgrid/rest v2.4.1+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE=
|
github.com/sendgrid/rest v2.4.1+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
|
@ -434,6 +439,7 @@ gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20171010053543-63abe20a23e2/go.mo
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
|
|
Loading…
Reference in New Issue