mirror of
https://shylinux.com/x/ContextOS
synced 2025-04-25 16:58:06 +08:00
add auth login
This commit is contained in:
parent
86fa642496
commit
2407699d6e
37
bin/boot.sh
37
bin/boot.sh
@ -1,9 +1,12 @@
|
||||
#! /bin/bash
|
||||
|
||||
export dev="https://shylinux.com"
|
||||
export box_root="/usr/local/context"
|
||||
export box_home="~/context"
|
||||
bench="bench"
|
||||
export ctx_dev=${ctx_dev:="https://shylinux.com"}
|
||||
export ctx_root="/usr/local/context"
|
||||
export ctx_home=~/context
|
||||
export ctx_bin="bench"
|
||||
|
||||
export user_cert=etc/user/cert.pem
|
||||
export user_key=etc/user/key.pem
|
||||
|
||||
log() {
|
||||
echo -e $*
|
||||
@ -15,7 +18,7 @@ prepare() {
|
||||
}
|
||||
|
||||
install() {
|
||||
[ -n "$1" ] && dev=$1 && shift
|
||||
[ -n "$1" ] && ctx_dev=$1 && shift
|
||||
case `uname -s` in
|
||||
"Darwin") GOOS=darwin GOARCH=amd64;;
|
||||
*) GOOS=linux GOARCH=386;;
|
||||
@ -24,15 +27,15 @@ install() {
|
||||
"x86_64") GOARCH=amd64;;
|
||||
"armv7l") GOARCH=arm;;
|
||||
esac
|
||||
log "dev: $dev\nGOOS: $GOOS\nGOARCH: $GOARCH"
|
||||
log "ctx_dev: $ctx_dev\nGOOS: $GOOS\nGOARCH: $GOARCH"
|
||||
|
||||
dev=$dev/code/upgrade
|
||||
wget -O etc/exit.shy $dev/exit_shy
|
||||
wget -O etc/init.shy $dev/init_shy
|
||||
wget -O etc/common.shy $dev/common_shy
|
||||
wget -O bin/bench "$dev/bench?GOOS=$GOOS&GOARCH=$GOARCH" && chmod u+x bin/bench
|
||||
wget -O bin/boot.sh $dev/boot_sh && chmod u+x bin/boot.sh
|
||||
wget -O bin/node.sh $dev/node_sh && chmod u+x bin/node.sh
|
||||
ctx_dev=$ctx_dev/code/upgrade
|
||||
wget -O etc/exit.shy $ctx_dev/exit_shy
|
||||
wget -O etc/init.shy $ctx_dev/init_shy
|
||||
wget -O etc/common.shy $ctx_dev/common_shy
|
||||
wget -O bin/bench "$ctx_dev/bench?GOOS=$GOOS&GOARCH=$GOARCH" && chmod u+x bin/bench
|
||||
wget -O bin/boot.sh $ctx_dev/boot_sh && chmod u+x bin/boot.sh
|
||||
wget -O bin/node.sh $ctx_dev/node_sh && chmod u+x bin/node.sh
|
||||
}
|
||||
|
||||
state() {
|
||||
@ -48,17 +51,17 @@ action() {
|
||||
|
||||
main() {
|
||||
while true; do
|
||||
$bench "$@" 2>var/log/boot.log && break
|
||||
$ctx_bin "$@" 2>var/log/boot.log && break
|
||||
log "restarting..." && sleep 3
|
||||
done
|
||||
}
|
||||
|
||||
dir=$box_root
|
||||
dir=$ctx_root
|
||||
[ -d "$1" ] && dir=$1 && shift
|
||||
[ -d "$dir" ] && cd $dir
|
||||
[ -f bin/bench ] && bench=bin/bench
|
||||
[ -f bin/bench ] && ctx_bin=bin/bench
|
||||
pid=`cat var/run/bench.pid`
|
||||
log "dir: $dir\nbench: $bench\npid: $pid"
|
||||
log "dir: $dir\nbench: $ctx_bin\npid: $pid"
|
||||
|
||||
case $1 in
|
||||
install) shift; prepare && install "$@";;
|
||||
|
13
bin/node.sh
13
bin/node.sh
@ -1,7 +1,12 @@
|
||||
#! /bin/bash
|
||||
|
||||
export box="http://localhost:9094"
|
||||
bench="bench"
|
||||
export ctx_box=${ctx_box:="http://localhost:9094"}
|
||||
export ctx_root="/usr/local/context"
|
||||
export ctx_home=~/context
|
||||
export ctx_bin="bench"
|
||||
|
||||
export user_cert=etc/user/cert.pem
|
||||
export user_key=etc/user/key.pem
|
||||
|
||||
log() {
|
||||
echo -e $*
|
||||
@ -14,13 +19,13 @@ prepare() {
|
||||
|
||||
main() {
|
||||
while true; do
|
||||
$bench "$@" 2>var/log/boot.log && break
|
||||
$ctx_bin "$@" 2>var/log/boot.log && break
|
||||
log "restarting..." && sleep 3
|
||||
done
|
||||
}
|
||||
|
||||
case $1 in
|
||||
create) mkdir $2 && cd $2 && shift && shift && prepare && main "$@";;
|
||||
create) mkdir $2; cd $2 && shift && shift && prepare && main "$@";;
|
||||
init) shift; prepare && main "$@";;
|
||||
*) mkdir -p var/run var/log && main "$@";;
|
||||
esac
|
||||
|
@ -1,3 +0,0 @@
|
||||
~web
|
||||
spide dev client new "https://shylinux.com"
|
||||
spide dev client new "http://172.20.10.12:9094"
|
@ -1,3 +1,5 @@
|
||||
source common.shy
|
||||
source local.shy
|
||||
~ssh
|
||||
remote auto
|
||||
|
||||
|
@ -9,13 +9,16 @@ import (
|
||||
crand "crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
"toolkit"
|
||||
@ -137,6 +140,11 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
||||
"key": &ctx.Config{Name: "key", Value: "etc/pem/key.pem", Help: "私钥文件"},
|
||||
},
|
||||
Commands: map[string]*ctx.Command{
|
||||
"init": &ctx.Command{Name: "init", Help: "数字摘要", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Conf("runtime", "user.cert", m.Cmdx("nfs.load", os.Getenv("user_cert")))
|
||||
m.Conf("runtime", "user.key", m.Cmdx("nfs.load", os.Getenv("user_key")))
|
||||
return
|
||||
}},
|
||||
"hash": &ctx.Command{Name: "hash [meta...]", Help: "数字摘要", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Cmdy("ctx.config", "hash")
|
||||
@ -624,7 +632,37 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
||||
return
|
||||
}},
|
||||
|
||||
"login": &ctx.Command{Name: "login nodesess", Help: "登录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Cmd("aaa.auth", "username", m.Option("username"), "session", "nodes").Table(func(sess map[string]string) {
|
||||
m.Cmd("aaa.auth", sess["key"], "nodes").Table(func(node map[string]string) {
|
||||
m.Add("append", "key", node["key"])
|
||||
m.Add("append", "meta", node["meta"])
|
||||
})
|
||||
})
|
||||
m.Table()
|
||||
return
|
||||
}
|
||||
m.Cmd("aaa.auth", arg[0], "username", m.Option("username"))
|
||||
return
|
||||
}},
|
||||
"share": &ctx.Command{Name: "share nodesess", Help: "共享", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Cmd("aaa.auth", "username", m.Option("username"), "session", "nodes").Table(func(sess map[string]string) {
|
||||
m.Cmd("aaa.auth", sess["key"], "nodes").Table(func(node map[string]string) {
|
||||
m.Add("key", node["key"])
|
||||
m.Add("meta", node["meta"])
|
||||
})
|
||||
})
|
||||
m.Table()
|
||||
return
|
||||
}
|
||||
m.Cmd("aaa.auth", arg[0], "username", m.Option("username"))
|
||||
return
|
||||
}},
|
||||
|
||||
"rsa": &ctx.Command{Name: "rsa gen|sign|verify|encrypt|decrypt|cert",
|
||||
Form: map[string]int{"common": -1},
|
||||
Help: []string{"gen: 生成密钥, sgin: 私钥签名, verify: 公钥验签, encrypt: 公钥加密, decrypt: 私钥解密",
|
||||
"密钥: rsa gen [keyfile [pubfile [certfile]]]",
|
||||
"加密: rsa encrypt pub content [enfile]",
|
||||
@ -650,11 +688,17 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
||||
public := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: pub}))
|
||||
m.Echo(m.Append("public", public))
|
||||
|
||||
common := map[string]interface{}{}
|
||||
for i := 0; i < len(m.Meta["common"]); i += 2 {
|
||||
kit.Chain(common, m.Meta["common"][i], m.Meta["common"][i+1])
|
||||
}
|
||||
|
||||
// 生成证书
|
||||
template := x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
IsCA: true,
|
||||
KeyUsage: x509.KeyUsageCertSign,
|
||||
Subject: pkix.Name{CommonName: kit.Format(common)},
|
||||
}
|
||||
cert, e := x509.CreateCertificate(crand.Reader, &template, &template, &keys.PublicKey, keys)
|
||||
m.Assert(e)
|
||||
@ -686,7 +730,11 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
||||
}
|
||||
case "verify":
|
||||
public, e := x509.ParsePKIXPublicKey(aaa.Decode(arg[1]))
|
||||
m.Assert(e)
|
||||
if e != nil {
|
||||
cert, e := x509.ParseCertificate(aaa.Decode(arg[1]))
|
||||
m.Assert(e)
|
||||
public = cert.PublicKey
|
||||
}
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
n, e := base64.StdEncoding.Decode(buf, Input(arg[2]))
|
||||
@ -742,6 +790,14 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
||||
if m.Echo(certificate); len(arg) > 4 {
|
||||
ioutil.WriteFile(arg[4], []byte(certificate), 0666)
|
||||
}
|
||||
case "info":
|
||||
cert, e := x509.ParseCertificate(aaa.Decode(arg[1]))
|
||||
m.Assert(e)
|
||||
|
||||
var common interface{}
|
||||
json.Unmarshal([]byte(cert.Subject.CommonName), &common)
|
||||
m.Put("option", "common", common).Cmdy("ctx.trans", "common", "format", "object")
|
||||
|
||||
case "check":
|
||||
defer func() {
|
||||
recover()
|
||||
|
@ -54,11 +54,6 @@ func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
||||
return &CLI{Context: c}
|
||||
}
|
||||
func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||
name, _ := os.Hostname()
|
||||
m.Conf("runtime", "hostname", name)
|
||||
m.Conf("runtime", "pid", os.Getpid())
|
||||
m.Conf("runtime", "GOOS", runtime.GOOS)
|
||||
m.Conf("runtime", "GOARCH", runtime.GOARCH)
|
||||
return cli
|
||||
}
|
||||
func (cli *CLI) Start(m *ctx.Message, arg ...string) bool {
|
||||
@ -103,13 +98,13 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
"nshell": &ctx.Cache{Name: "nshell", Value: "0", Help: "终端数量"},
|
||||
},
|
||||
Configs: map[string]*ctx.Config{
|
||||
"runtime": &ctx.Config{Name: "runtime", Value: map[string]interface{}{}, Help: "运行环境"},
|
||||
"runtime": &ctx.Config{Name: "runtime", Value: map[string]interface{}{
|
||||
"init_env": []interface{}{"ctx_dev", "ctx_box", "ctx_root", "ctx_home", "USER"},
|
||||
"script": map[string]interface{}{"sh": "bash", "shy": "source", "py": "python"},
|
||||
"init_shy": "etc/init.shy", "exit_shy": "etc/exit.shy",
|
||||
"web_port": ":9094", "ssh_port": ":9090",
|
||||
}, Help: "运行环境"},
|
||||
|
||||
"init_shy": &ctx.Config{Name: "init_shy", Value: "etc/init.shy", Help: "启动脚本"},
|
||||
"exit_shy": &ctx.Config{Name: "exit_shy", Value: "etc/exit.shy", Help: "启动脚本"},
|
||||
"cmd_script": &ctx.Config{Name: "cmd_script", Value: map[string]interface{}{
|
||||
"sh": "bash", "shy": "source", "py": "python",
|
||||
}, Help: "系统命令超时"},
|
||||
"alias": &ctx.Config{Name: "alias", Value: map[string]interface{}{
|
||||
"~": []string{"context"},
|
||||
"!": []string{"message"},
|
||||
@ -139,6 +134,33 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
"timer_next": &ctx.Config{Name: "timer_next", Value: "", Help: "定时器"},
|
||||
},
|
||||
Commands: map[string]*ctx.Command{
|
||||
"init": &ctx.Command{Name: "init", Help: "停止服务", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Conf("runtime", "GOARCH", runtime.GOARCH)
|
||||
m.Conf("runtime", "GOOS", runtime.GOOS)
|
||||
m.Conf("runtime", "pid", os.Getpid())
|
||||
|
||||
if name, e := os.Hostname(); e == nil {
|
||||
m.Conf("runtime", "hostname", name)
|
||||
}
|
||||
if name, e := os.Getwd(); e == nil {
|
||||
_, file := path.Split(name)
|
||||
m.Conf("runtime", "pathname", file)
|
||||
}
|
||||
m.Confm("runtime", "init_env", func(index int, key string) {
|
||||
m.Conf("runtime", key, os.Getenv(key))
|
||||
})
|
||||
|
||||
if m.Confs("runtime", "ctx_box") {
|
||||
m.Conf("runtime", "node.type", "worker")
|
||||
m.Conf("runtime", "node.name", m.Conf("runtime", "pathname"))
|
||||
} else {
|
||||
m.Conf("runtime", "node.type", "server")
|
||||
m.Conf("runtime", "node.name", strings.Replace(m.Conf("runtime", "hostname"), ".", "_", -1))
|
||||
}
|
||||
m.Conf("runtime", "node.route", m.Conf("runtime", "node.name"))
|
||||
|
||||
return
|
||||
}},
|
||||
"source": &ctx.Command{Name: "source [script|stdio|snippet]", Help: "解析脚本, script: 脚本文件, stdio: 命令终端, snippet: 代码片段", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Cmdy("dir", "", "dir_deep", "dir_reg", ".*\\.(sh|shy|py)$")
|
||||
@ -155,7 +177,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
m.Start(fmt.Sprintf("shell%d", m.Capi("nshell", 1)), "shell", arg...)
|
||||
m.Wait()
|
||||
default:
|
||||
m.Cmdy("system", m.Conf("cmd_script", strings.TrimPrefix(path.Ext(p), ".")), arg)
|
||||
m.Cmdy("system", m.Conf("runtime", []string{"script", strings.TrimPrefix(path.Ext(p), ".")}), arg)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -376,7 +398,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
|
||||
// 解析脚本
|
||||
msg := m
|
||||
for k, v := range m.Confv("cmd_script").(map[string]interface{}) {
|
||||
for k, v := range m.Confv("runtime", "script").(map[string]interface{}) {
|
||||
if strings.HasSuffix(detail[0], "."+k) {
|
||||
msg = m.Spawn(m.Optionv("ps_target"))
|
||||
detail[0] = m.Cmdx("nfs.path", detail[0])
|
||||
|
@ -38,21 +38,14 @@ func (ctx *CTX) Begin(m *Message, arg ...string) Server {
|
||||
return ctx
|
||||
}
|
||||
func (ctx *CTX) Start(m *Message, arg ...string) bool {
|
||||
m.Optionv("ps_target", Index)
|
||||
if len(arg) > 0 && arg[0] == "daemon" {
|
||||
m.Options("daemon", true)
|
||||
arg = arg[1:]
|
||||
}
|
||||
|
||||
m.Cmd("log.init")
|
||||
m.Cmd("gdb.init")
|
||||
if m.Cmd("yac.init", "lex"); len(arg) == 0 {
|
||||
m.Cmd("ctx.init")
|
||||
if m.Optionv("ps_target", Index); len(arg) == 0 {
|
||||
m.Cap("stream", "shy")
|
||||
m.Cmd("cli.source", "init.shy").Cmd("cli.source", "stdio").Cmd("cli.source", "exit.shy")
|
||||
return true
|
||||
m.Cmd("cli.source", m.Conf("runtime", "init_shy")).Cmd("cli.source", "stdio").Cmd("cli.source", m.Conf("runtime", "exit_shy"))
|
||||
} else {
|
||||
m.Cmd("cli.source", arg)
|
||||
}
|
||||
|
||||
m.Cmd("cli.source", arg)
|
||||
return true
|
||||
}
|
||||
func (ctx *CTX) Close(m *Message, arg ...string) bool {
|
||||
@ -96,6 +89,12 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
|
||||
"time_format": &Config{Name: "time_format", Value: "2006-01-02 15:04:05", Help: "时间格式"},
|
||||
},
|
||||
Commands: map[string]*Command{
|
||||
"init": &Command{Name: "init", Help: "启动", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
|
||||
for _, x := range []string{"cli", "yac", "nfs", "aaa", "log", "web", "gdb"} {
|
||||
m.Cmd(x + ".init")
|
||||
}
|
||||
return
|
||||
}},
|
||||
"help": &Command{Name: "help topic", Help: "帮助", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Echo("usage: help context [module [command|config|cache name]]\n")
|
||||
@ -1038,8 +1037,10 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
|
||||
m.Add("append", "value", fmt.Sprintf("%s", string(b)))
|
||||
}
|
||||
}
|
||||
if m.Option("format") != "object" {
|
||||
m.Sort("key", "str")
|
||||
}
|
||||
m.Table()
|
||||
// m.Sort("key", "str").Table()
|
||||
case map[string]string:
|
||||
for k, v := range val {
|
||||
m.Add("append", "key", k)
|
||||
|
@ -330,6 +330,9 @@ func (m *Message) Time(arg ...interface{}) string {
|
||||
} else if len(arg) > 0 {
|
||||
str = fmt.Sprintf("%v", arg[0])
|
||||
}
|
||||
if str == "stamp" {
|
||||
return kit.Format(t.Unix())
|
||||
}
|
||||
return t.Format(str)
|
||||
}
|
||||
func (m *Message) Code() int {
|
||||
@ -1102,9 +1105,7 @@ func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message))
|
||||
}
|
||||
func (m *Message) GoFunc(msg *Message, hand ...func(msg *Message)) *Message {
|
||||
go func() {
|
||||
m.Log("info", "%v safe go begin", m.Capi("ngo", 1))
|
||||
m.TryCatch(msg, true, hand...)
|
||||
m.Log("info", "%v safe go end", m.Capi("ngo", -1)+1)
|
||||
}()
|
||||
return m
|
||||
}
|
||||
|
@ -324,6 +324,9 @@ var Index = &ctx.Context{Name: "lex", Help: "词法中心",
|
||||
"info": &ctx.Config{Name: "info", Value: map[string]interface{}{"compact": true, "ncell": 128, "nlang": 64}, Help: "嵌套层级日志的标记"},
|
||||
},
|
||||
Commands: map[string]*ctx.Command{
|
||||
"init": &ctx.Command{Name: "init", Help: "启动", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
return
|
||||
}},
|
||||
"spawn": &ctx.Command{Name: "spawn", Help: "添加词法规则", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if _, ok := m.Target().Server.(*LEX); m.Assert(ok) {
|
||||
m.Start(fmt.Sprintf("matrix%d", m.Capi("nmat", 1)), "matrix")
|
||||
|
@ -905,7 +905,10 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
|
||||
for i := m.Capi("ninput") - 1; i < m.Capi("ninput"); i++ {
|
||||
line = m.Conf("input", []interface{}{i, "line"})
|
||||
|
||||
msg := m.Backs(m.Spawn(m.Source()).Set("detail", line).Set("option", "file_pos", i))
|
||||
msg := m.Backs(m.Spawn(m.Source()).Set(
|
||||
"detail", line).Set(
|
||||
"option", "file_pos", i).Set(
|
||||
"option", "username", m.Conf("runtime", "USER")))
|
||||
|
||||
nfs.printf(m.Conf("prompt"), line)
|
||||
nfs.printf(msg.Meta["result"])
|
||||
@ -932,6 +935,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
|
||||
case msg = <-nfs.send:
|
||||
code = msg.Code()
|
||||
nfs.hand[code] = msg
|
||||
msg.Option("username", m.Conf("runtime", "USER"))
|
||||
case msg = <-nfs.echo:
|
||||
code, meta, body = msg.Optioni("remote_code"), "result", "append"
|
||||
}
|
||||
@ -1108,9 +1112,14 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
||||
"limit": "10",
|
||||
},
|
||||
}, Help: "命令集合"},
|
||||
"paths": &ctx.Config{Name: "paths", Value: []interface{}{"var", "usr", "etc", ""}, Help: "文件路径"},
|
||||
"paths": &ctx.Config{Name: "paths", Value: []interface{}{"var", "usr", "etc", "bin", ""}, Help: "文件路径"},
|
||||
},
|
||||
Commands: map[string]*ctx.Command{
|
||||
"init": &ctx.Command{Name: "init", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Conf("paths", -2, m.Conf("runtime", "ctx_home"))
|
||||
m.Conf("paths", -2, m.Conf("runtime", "ctx_root"))
|
||||
return
|
||||
}},
|
||||
"pwd": &ctx.Command{Name: "pwd [all] | [[index] path] ", Help: "工作目录,all: 查看所有, index path: 设置路径, path: 设置当前路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) > 0 && arg[0] == "all" {
|
||||
m.Cmdy("nfs.config", "paths")
|
||||
|
@ -35,64 +35,113 @@ func (ssh *SSH) Close(m *ctx.Message, arg ...string) bool {
|
||||
var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
||||
Caches: map[string]*ctx.Cache{
|
||||
"nnode": &ctx.Cache{Name: "nnode", Value: "0", Help: "节点数量"},
|
||||
"nodename": &ctx.Cache{Name: "nodename", Value: "shy", Help: "本机域名"},
|
||||
"nodename": &ctx.Cache{Name: "nodename", Value: "dev", Help: "本机域名"},
|
||||
},
|
||||
Configs: map[string]*ctx.Config{
|
||||
"node": &ctx.Config{Name: "node", Value: map[string]interface{}{}, Help: "主机信息"},
|
||||
"hostport": &ctx.Config{Name: "hostport", Value: "", Help: "主机域名"},
|
||||
"nodename": &ctx.Config{Name: "nodename", Value: "com", Help: "主机域名"},
|
||||
"current": &ctx.Config{Name: "current", Value: "", Help: "当前主机"},
|
||||
"timer": &ctx.Config{Name: "timer", Value: "", Help: "当前主机"},
|
||||
},
|
||||
Commands: map[string]*ctx.Command{
|
||||
"remote": &ctx.Command{Name: "remote listen|dial args...", Help: "远程连接", Form: map[string]int{"right": 1, "nodename": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
"remote": &ctx.Command{Name: "remote listen|dial args...", Help: "远程连接", Form: map[string]int{"right": 1, "nodename": 1, "nodetype": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 { // 查看主机
|
||||
m.Cmdy("ctx.config", "node")
|
||||
return
|
||||
}
|
||||
|
||||
switch arg[0] {
|
||||
case "auto":
|
||||
if m.Cmd("ssh.remote", "dial", "consul", "/shadow"); !m.Confs("runtime", "ctx_box") && m.Confs("runtime", "ssh_port") {
|
||||
m.Cmd("ssh.remote", "listen", m.Conf("runtime", "ssh_port"))
|
||||
m.Cmd("web.serve", "usr", m.Conf("runtime", "web_port"))
|
||||
}
|
||||
|
||||
case "listen":
|
||||
m.Call(func(nfs *ctx.Message) *ctx.Message {
|
||||
if nfs.Options("hostport") { // 监听端口
|
||||
m.Conf("runtime", "ssh_port", nfs.Option("hostport"))
|
||||
}
|
||||
if !m.Confs("runtime", "node.sess") {
|
||||
if !m.Confs("runtime", "node.cert") { // 设备注册
|
||||
msg := m.Cmd("aaa.rsa", "gen", "common", m.Confv("runtime", "node"))
|
||||
m.Conf("runtime", "node.cert", msg.Append("certificate"))
|
||||
m.Conf("runtime", "node.key", msg.Append("private"))
|
||||
m.Cmd("aaa.auth", "nodes", m.Conf("runtime", "node.route"), "cert", msg.Append("certificate"))
|
||||
|
||||
sess := m.Cmdx("aaa.sess", "nodes", "username", m.Conf("runtime", "USER"))
|
||||
m.Cmdx("aaa.auth", sess, "nodes", m.Conf("runtime", "node.route"))
|
||||
m.Cmdx("aaa.auth", "username", m.Conf("runtime", "USER"), "userrole", "root")
|
||||
|
||||
}
|
||||
m.Conf("runtime", "node.sess", m.Cmdx("web.get", "dev", "/login",
|
||||
"cert", m.Confv("runtime", "node.cert"), "temp", "sess.0"))
|
||||
}
|
||||
|
||||
return nil
|
||||
}, "nfs.remote", arg)
|
||||
|
||||
case "redial": // 断线重连
|
||||
if !m.Caps("nodename") {
|
||||
m.Cmdx("remote", "dial", arg[1:])
|
||||
}
|
||||
case "listen", "dial":
|
||||
case "dial":
|
||||
m.Call(func(nfs *ctx.Message) *ctx.Message {
|
||||
if arg[0] == "listen" && nfs.Options("hostport") { // 监听端口
|
||||
m.Conf("hostport", nfs.Option("hostport"))
|
||||
if m.Confs("timer") { // 断线重连
|
||||
m.Conf("timer", m.Cmdx("cli.timer", "delete", m.Conf("timer")))
|
||||
}
|
||||
|
||||
} else if arg[0] == "dial" {
|
||||
if m.Confs("timer") { // 断线重连
|
||||
m.Conf("timer", m.Cmdx("cli.timer", "delete", m.Conf("timer")))
|
||||
m.Spawn(nfs.Target()).Call(func(node *ctx.Message) *ctx.Message {
|
||||
m.Confv("node", node.Result(1), map[string]interface{}{ // 添加主机
|
||||
"create_time": m.Time(),
|
||||
"access_time": m.Time(),
|
||||
"nodename": node.Result(1),
|
||||
"nodetype": "master",
|
||||
"module": nfs.Format("target"),
|
||||
|
||||
"username": m.Option("right"),
|
||||
"cm_target": "ctx.web.code",
|
||||
})
|
||||
|
||||
m.Conf("runtime", "node.route", node.Result(2)+"."+node.Result(0))
|
||||
if !m.Confs("runtime", "node.sess") { // 设备注册
|
||||
if !m.Confs("runtime", "node.cert") {
|
||||
msg := m.Cmd("aaa.rsa", "gen", "common", m.Confv("runtime", "node"))
|
||||
m.Conf("runtime", "node.cert", msg.Append("certificate"))
|
||||
m.Conf("runtime", "node.key", msg.Append("private"))
|
||||
}
|
||||
m.Conf("runtime", "node.sess", m.Cmdx("web.get", "dev", "/login",
|
||||
"cert", m.Confv("runtime", "node.cert"), "temp", "sess.0"))
|
||||
}
|
||||
|
||||
m.Spawn(nfs.Target()).Call(func(node *ctx.Message) *ctx.Message {
|
||||
m.Confv("node", node.Result(1), map[string]interface{}{ // 添加主机
|
||||
"module": nfs.Format("target"),
|
||||
"create_time": m.Time(),
|
||||
"access_time": m.Time(),
|
||||
"username": m.Option("right"),
|
||||
"cm_target": "ctx.web.code",
|
||||
})
|
||||
if !m.Confs("runtime", "user.name") && m.Confs("runtime", "user.key") { // 用户注册
|
||||
user := m.Cmd("web.get", "dev", "/login", "username", m.Conf("runtime", "USER"),
|
||||
"user.cert", m.Conf("runtime", "user.cert"), "temp", "data", "format", "object")
|
||||
m.Conf("runtime", "user.name", user.Append("username"))
|
||||
}
|
||||
|
||||
m.Cap("stream", nfs.Format("target"))
|
||||
m.Cap("nodename", node.Result(0))
|
||||
if !m.Confs("current") {
|
||||
m.Conf("current", node.Result(1))
|
||||
}
|
||||
if m.Confs("runtime", "user.name") { // 绑定用户
|
||||
msg := m.Cmd("web.get", "dev", "/login", "username", m.Conf("runtime", "user.name"),
|
||||
"bind", m.Conf("runtime", "node.route"), "code", m.Cmdx("aaa.rsa", "sign", m.Conf("runtime", "user.key"), m.Conf("runtime", "node.route")), "temp", "data", "format", "object")
|
||||
m.Cmd("aaa.auth", "username", m.Conf("runtime", "user.name"), "userrole", msg.Append("userrole"))
|
||||
}
|
||||
|
||||
nfs.Free(func(nfs *ctx.Message) bool { // 连接中断
|
||||
m.Conf("timer", m.Cmdx("cli.timer", "repeat", "10s", "context", "ssh", "remote", "redial", arg[1:]))
|
||||
m.Cap("stream", nfs.Format("target"))
|
||||
if !m.Confs("current") {
|
||||
m.Conf("current", node.Result(1))
|
||||
}
|
||||
|
||||
m.Log("info", "delete node %s", node.Result(1))
|
||||
delete(m.Confm("node"), node.Result(1))
|
||||
m.Cap("nodename", "")
|
||||
m.Cap("stream", "")
|
||||
return true
|
||||
})
|
||||
return nil
|
||||
}, "send", "recv", "add", m.Confx("nodename"))
|
||||
}
|
||||
nfs.Free(func(nfs *ctx.Message) bool { // 连接中断
|
||||
m.Conf("timer", m.Cmdx("cli.timer", "repeat", "10s", "context", "ssh", "remote", "redial", arg[1:]))
|
||||
|
||||
m.Log("info", "delete node %s", node.Result(1))
|
||||
delete(m.Confm("node"), node.Result(1))
|
||||
m.Cap("nodename", "")
|
||||
m.Cap("stream", "")
|
||||
return true
|
||||
})
|
||||
return nil
|
||||
}, "send", "recv", "add", m.Conf("runtime", "node.name"), m.Conf("runtime", "node.type"))
|
||||
return nil
|
||||
}, "nfs.remote", arg)
|
||||
case "recv":
|
||||
@ -100,11 +149,14 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
||||
case "add":
|
||||
if node := m.Confm("node", arg[2]); node == nil { // 添加主机
|
||||
m.Confv("node", arg[2], map[string]interface{}{
|
||||
"module": m.Format("source"),
|
||||
"create_time": m.Time(),
|
||||
"access_time": m.Time(),
|
||||
"username": m.Option("right"),
|
||||
"cm_target": "ctx.web.code",
|
||||
"nodename": arg[2],
|
||||
"nodetype": arg[3],
|
||||
"module": m.Format("source"),
|
||||
|
||||
"username": m.Option("right"),
|
||||
"cm_target": "ctx.web.code",
|
||||
})
|
||||
} else if len(arg) > 3 && arg[3] == kit.Format(node["token"]) { // 断线重连
|
||||
node["access_time"] = m.Time()
|
||||
@ -112,11 +164,14 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
||||
} else { // 域名冲突
|
||||
arg[2] = fmt.Sprintf("%s_%d", arg[2], m.Capi("nnode", 1))
|
||||
m.Confv("node", arg[2], map[string]interface{}{
|
||||
"module": m.Format("source"),
|
||||
"create_time": m.Time(),
|
||||
"access_time": m.Time(),
|
||||
"username": m.Option("right"),
|
||||
"cm_target": "ctx.web.code",
|
||||
"nodename": arg[2],
|
||||
"nodetype": arg[3],
|
||||
"module": m.Format("source"),
|
||||
|
||||
"username": m.Option("right"),
|
||||
"cm_target": "ctx.web.code",
|
||||
})
|
||||
}
|
||||
|
||||
@ -124,7 +179,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
||||
m.Conf("current", arg[2])
|
||||
}
|
||||
|
||||
m.Echo(arg[2]).Echo(m.Cap("nodename")).Back(m)
|
||||
m.Echo(arg[2]).Echo(m.Conf("runtime", "node.name")).Echo(m.Conf("runtime", "node.route")).Back(m)
|
||||
m.Sess("ms_source", false).Free(func(msg *ctx.Message) bool { // 断线清理
|
||||
m.Log("info", "delete node %s", arg[2])
|
||||
delete(m.Confm("node"), arg[2])
|
||||
@ -133,26 +188,60 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
||||
}
|
||||
|
||||
default:
|
||||
if !m.Options("sign_source") { // 数字签名
|
||||
hash, meta := kit.Hash("rand",
|
||||
m.Option("sign_time", m.Time("stamp")),
|
||||
m.Option("sign_username", m.Option("username")),
|
||||
m.Option("sign_source", m.Conf("runtime", "node.route")),
|
||||
m.Option("sign_target", arg[0]),
|
||||
m.Option("sign_cmd", strings.Join(arg[1:], " ")),
|
||||
)
|
||||
m.Option("sign_rand", meta[0])
|
||||
m.Option("sign_code", m.Cmdx("aaa.rsa", "sign", m.Conf("runtime", "node.key"), m.Option("sign_hash", hash)))
|
||||
}
|
||||
|
||||
names, arg := strings.SplitN(arg[0], ".", 2), arg[1:]
|
||||
|
||||
if names[0] == "" { // 本地执行
|
||||
node := m.Confm("node", m.Option("nodename"))
|
||||
user := kit.Format(kit.Chain(node, "username"))
|
||||
hash, _ := kit.Hash(
|
||||
m.Option("sign_rand"),
|
||||
m.Option("sign_time"),
|
||||
m.Option("sign_username"),
|
||||
m.Option("sign_source"),
|
||||
m.Option("sign_target"),
|
||||
m.Option("sign_cmd"),
|
||||
)
|
||||
|
||||
sessid := m.Cmd("aaa.user", user, "ssh").Append("key")
|
||||
if sessid == "" { // 创建会话
|
||||
sessid = m.Cmdx("aaa.sess", "ssh", "ip", "what")
|
||||
m.Cmd("aaa.sess", sessid, user, "ppid", "what")
|
||||
// 创建会话
|
||||
if m.Option("sessid", m.Cmd("aaa.auth", "nodes", m.Option("sign_source"), "session").Append("key")); !m.Options("sessid") {
|
||||
m.Option("sessid", m.Cmdx("aaa.sess", "nodes", "nodes", m.Option("sign_source")))
|
||||
}
|
||||
|
||||
bench := m.Cmd("aaa.sess", sessid, "bench").Append("key")
|
||||
if bench == "" { // 创建空间
|
||||
bench = m.Cmdx("aaa.work", sessid, "ssh")
|
||||
// 绑定设备
|
||||
m.Option("username", m.Cmd("aaa.sess", m.Option("sessid"), "username").Append("meta"))
|
||||
if !m.Options("username") || !m.Cmds("aaa.auth", "nodes", m.Option("sign_source"), "cert") {
|
||||
msg := m.Cmd("web.get", "dev", "/login", "pull", m.Option("sign_source"), "temp", "data", "format", "object")
|
||||
if m.Cmds("aaa.auth", "nodes", m.Option("sign_source"), "cert", msg.Append("cert")); m.Appends("username") {
|
||||
m.Cmds("aaa.auth", m.Option("sessid"), "username", m.Option("username", msg.Append("username")))
|
||||
} else {
|
||||
m.Log("fuck", "no username")
|
||||
}
|
||||
}
|
||||
|
||||
if m.Cmds("aaa.work", bench, "right", user, "remote", arg[0]) { // 执行命令
|
||||
msg := m.Find(m.Option("current_ctx", kit.Format(node["cm_target"]))).Cmd(arg).CopyTo(m)
|
||||
node["cm_target"] = msg.Cap("module")
|
||||
// 验证签名
|
||||
if !m.Cmds("aaa.rsa", "verify", m.Cmd("aaa.auth", "nodes", m.Option("sign_source"), "cert").Append("meta"), m.Option("sign_code"), hash) {
|
||||
m.Log("fuck", "sign failure")
|
||||
return
|
||||
}
|
||||
|
||||
// 创建空间
|
||||
if m.Option("bench", m.Cmd("aaa.sess", m.Option("sessid"), "bench").Append("key")); !m.Options("bench") {
|
||||
m.Option("bench", m.Cmdx("aaa.work", m.Option("sessid"), "nodes"))
|
||||
}
|
||||
|
||||
m.Option("current_ctx", kit.Select("ssh", m.Cmdx("aaa.auth", m.Option("bench"), "data", "target")))
|
||||
if m.Cmds("aaa.work", m.Option("bench"), "right", m.Option("username"), "remote", arg[0]) { // 执行命令
|
||||
msg := m.Find(m.Option("current_ctx")).Cmd(arg).CopyTo(m)
|
||||
m.Cmd("aaa.auth", m.Option("bench"), "data", "target", msg.Cap("module"))
|
||||
} else {
|
||||
m.Echo("no right %s %s", "remote", arg[0])
|
||||
}
|
||||
@ -170,7 +259,8 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
||||
}
|
||||
|
||||
rest := kit.Select("", names, 1)
|
||||
m.Option("nodename", m.Cap("nodename"))
|
||||
m.Option("username", m.Option("username"))
|
||||
m.Option("nodename", m.Conf("runtime", "node.name"))
|
||||
|
||||
if names[0] == "*" { // 广播命令
|
||||
m.Confm("node", func(name string, node map[string]interface{}) {
|
||||
|
@ -58,8 +58,7 @@ func (tcp *TCP) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||
}
|
||||
func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool {
|
||||
if arg[1] == "consul" {
|
||||
arg[1] = m.Cmdx("web.get", "", arg[2], "temp", "hostport.0")
|
||||
if arg[1] == "" {
|
||||
if arg[1] = m.Cmdx("web.get", "dev", arg[2], "temp", "hostport.0"); arg[1] == "" {
|
||||
return true
|
||||
}
|
||||
for i := 2; i < len(arg)-1; i++ {
|
||||
|
@ -142,18 +142,16 @@ func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) {
|
||||
msg.Option("path", r.URL.Path)
|
||||
msg.Optionv("debug", false)
|
||||
|
||||
msg.Option("GOOS", m.Conf("runtime", "GOOS"))
|
||||
msg.Option("GOOS", m.Conf("runtime", "GOARCH"))
|
||||
agent := r.Header.Get("User-Agent")
|
||||
switch {
|
||||
case strings.Contains(agent, "Macintosh"):
|
||||
msg.Option("GOOS", "darwin")
|
||||
default:
|
||||
msg.Option("GOOS", "linux")
|
||||
}
|
||||
switch {
|
||||
case strings.Contains(agent, "Intel"):
|
||||
msg.Option("GOARCH", "386")
|
||||
default:
|
||||
msg.Option("GOARCH", "386")
|
||||
}
|
||||
|
||||
msg.Option("dir_root", msg.Cap("directory"))
|
||||
@ -397,6 +395,10 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
||||
}, Help: "工具列表"},
|
||||
},
|
||||
Commands: map[string]*ctx.Command{
|
||||
"init": &ctx.Command{Name: "init", Help: "post请求", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Cmd("web.spide", "dev", "client", "new", kit.Select(m.Conf("runtime", "ctx_dev"), m.Conf("runtime", "ctx_box")))
|
||||
return
|
||||
}},
|
||||
"spide": &ctx.Command{Name: "spide [which [client|cookie [name [value]]]]", Help: "爬虫配置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
switch len(arg) {
|
||||
case 0:
|
||||
@ -563,6 +565,9 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
||||
m.Conf("spide", []string{which, "cookie", v.Name}, v.Value)
|
||||
m.Log("info", "get-cookie %s: %v", v.Name, v.Value)
|
||||
}
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return nil
|
||||
}
|
||||
|
||||
var result interface{}
|
||||
ct := res.Header.Get("Content-Type")
|
||||
@ -1021,6 +1026,40 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
||||
http.ServeFile(w, r, p)
|
||||
return
|
||||
}},
|
||||
"/shadow": &ctx.Command{Name: "/shadow", Help: "暗网", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Append("hostport", m.Conf("runtime", "ssh_port"))
|
||||
return
|
||||
}},
|
||||
"/login": &ctx.Command{Name: "/login", Help: "认证", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
switch {
|
||||
case m.Options("cert"): // 注册证书
|
||||
msg := m.Cmd("aaa.rsa", "info", m.Option("cert"))
|
||||
m.Cmd("aaa.auth", "nodes", msg.Append("route"), "cert", m.Option("cert"))
|
||||
m.Append("sess", m.Cmdx("aaa.sess", "nodes", "nodes", msg.Append("route")))
|
||||
|
||||
case m.Options("pull"): // 下载证书
|
||||
sess := m.Cmd("aaa.auth", "nodes", m.Option("pull"), "session").Append("key")
|
||||
m.Add("append", "username", m.Cmd("aaa.auth", sess, "username").Append("meta"))
|
||||
m.Add("append", "cert", (m.Cmd("aaa.auth", "nodes", m.Option("pull"), "cert").Append("meta")))
|
||||
|
||||
case m.Options("bind"): // 绑定设备
|
||||
sess := m.Cmd("aaa.auth", "nodes", m.Option("bind"), "session").Append("key")
|
||||
if m.Cmd("aaa.auth", sess, "username").Appends("meta") {
|
||||
return // 已经绑定
|
||||
}
|
||||
|
||||
if m.Cmds("aaa.rsa", "verify", m.Cmd("aaa.auth", "username", m.Option("username"), "cert").Append("meta"), m.Option("code"), m.Option("bind")) {
|
||||
m.Cmd("aaa.login", sess, "username", m.Option("username"))
|
||||
m.Append("userrole", "root")
|
||||
}
|
||||
case m.Options("user.cert"): // 用户注册
|
||||
if !m.Cmds("aaa.auth", "username", m.Option("username"), "cert") {
|
||||
m.Cmd("aaa.auth", "username", m.Option("username"), "cert", m.Option("user.cert"))
|
||||
}
|
||||
m.Append("username", m.Option("username"))
|
||||
}
|
||||
return
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -341,9 +341,6 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
|
||||
yac.mat = make([]map[byte]*State, m.Confi("info", "nlang"))
|
||||
yac.state = map[State]*State{}
|
||||
|
||||
if len(arg) > 0 {
|
||||
yac.lex = m.Sess(arg[0])
|
||||
}
|
||||
m.Confm("seed", func(line int, seed map[string]interface{}) {
|
||||
m.Spawn().Cmd("train", seed["page"], seed["hash"], seed["word"])
|
||||
})
|
||||
|
@ -54,7 +54,9 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
|
||||
}, Help: "聊天记录"},
|
||||
"mp": &ctx.Config{Name: "chat", Value: map[string]interface{}{
|
||||
"appid": "", "appmm": "", "token": "", "site": "https://shylinux.com",
|
||||
"auth": "/sns/jscode2session?grant_type=authorization_code",
|
||||
"auth": "/sns/jscode2session?grant_type=authorization_code",
|
||||
"tool_path": "/Applications/wechatwebdevtools.app/Contents/MacOS/cli",
|
||||
"project_path": "/Users/shaoying/context/usr/client/mp",
|
||||
}, Help: "聊天记录"},
|
||||
},
|
||||
Commands: map[string]*ctx.Command{
|
||||
@ -210,6 +212,10 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
|
||||
}
|
||||
return
|
||||
}},
|
||||
"mp": &ctx.Command{Name: "mp", Help: "talk", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Cmdy("cli.system", m.Conf("mp", "tool_path"), arg, m.Conf("mp", "project_path"), "cmd_active", "true")
|
||||
return
|
||||
}},
|
||||
|
||||
"talk": &ctx.Command{Name: "talk", Help: "talk", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if m.Confs("default") {
|
||||
|
@ -244,10 +244,13 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心",
|
||||
}
|
||||
}
|
||||
|
||||
m.Log("fuck", "what %v", p)
|
||||
if _, e = os.Stat(p); e != nil {
|
||||
list := strings.Split(key, "/")
|
||||
m.Log("fuck", "what %v", list)
|
||||
p = m.Cmdx("nfs.path", m.Conf("upgrade", []string{"file", list[len(list)-1]}))
|
||||
}
|
||||
m.Log("fuck", "what %v", p)
|
||||
|
||||
m.Log("info", "upgrade %s %s", p, m.Cmdx("aaa.hash", "file", p))
|
||||
http.ServeFile(m.Optionv("response").(http.ResponseWriter), m.Optionv("request").(*http.Request), p)
|
||||
@ -319,10 +322,6 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心",
|
||||
}
|
||||
return
|
||||
}},
|
||||
"/consul": &ctx.Command{Name: "/consul", Help: "下载文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Append("hostport", m.Cmdx("ssh.config", "hostport"))
|
||||
return
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user