1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-26 09:14:06 +08:00
This commit is contained in:
shaoying 2019-01-13 09:27:25 +08:00
parent a95dd9a346
commit 40df0b8f53
7 changed files with 366 additions and 323 deletions

View File

@ -1018,6 +1018,24 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
m.Table() m.Table()
return return
} }
switch arg[0] {
case "stop":
if timer := m.Confm("timer", arg[1]); timer != nil {
timer["stop"] = true
}
cli.schedule(m)
return
case "start":
if timer := m.Confm("timer", arg[1]); timer != nil {
timer["stop"] = false
}
cli.schedule(m)
return
case "delete":
delete(m.Confm("timer"), arg[1])
cli.schedule(m)
return
}
now := int64(m.Sess("cli").Cmd("time").Appendi("timestamp")) now := int64(m.Sess("cli").Cmd("time").Appendi("timestamp"))
begin := now begin := now
@ -1046,6 +1064,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
"repeat": repeat, "repeat": repeat,
"order": order, "order": order,
"done": false, "done": false,
"stop": false,
"time": arg[0], "time": arg[0],
"cmd": arg[1:], "cmd": arg[1:],
"msg": 0, "msg": 0,
@ -1062,7 +1081,8 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
if m.Conf("timer_next") == "" { if m.Conf("timer_next") == "" {
break break
} }
timer := m.Confv("timer", m.Conf("timer_next")).(map[string]interface{})
if timer := m.Confm("timer", m.Conf("timer_next")); timer != nil && !kit.Right(timer["stop"]) {
m.Log("info", "timer %s %v", m.Conf("timer_next"), timer["cmd"]) m.Log("info", "timer %s %v", m.Conf("timer_next"), timer["cmd"])
msg := m.Sess("cli").Cmd("source", timer["cmd"]) msg := m.Sess("cli").Cmd("source", timer["cmd"])
@ -1074,6 +1094,8 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
} else { } else {
timer["done"] = true timer["done"] = true
} }
}
cli.schedule(m) cli.schedule(m)
} }
} }

View File

@ -156,6 +156,9 @@ func (c *Context) Start(m *Message, arg ...string) bool {
c.Close(m, m.Meta["detail"]...) c.Close(m, m.Meta["detail"]...)
c.exit <- true c.exit <- true
} }
}, func(m *Message) {
c.Close(m, m.Meta["detail"]...)
c.exit <- true
}) })
if sync { if sync {
@ -173,8 +176,9 @@ func (c *Context) Close(m *Message, arg ...string) bool {
if m.target == c { if m.target == c {
for i := len(c.requests) - 1; i >= 0; i-- { for i := len(c.requests) - 1; i >= 0; i-- {
if msg := c.requests[i]; msg.code == m.code { if msg := c.requests[i]; msg.code == m.code {
m.Log("close", "request %d/%d", i, len(c.requests)-1)
if c.Server == nil || c.Server.Close(m, arg...) { if c.Server == nil || c.Server.Close(m, arg...) {
m.Log("close", "request %d/%d", i, len(c.requests)-1)
msg.Free()
for j := i; j < len(c.requests)-1; j++ { for j := i; j < len(c.requests)-1; j++ {
c.requests[j] = c.requests[j+1] c.requests[j] = c.requests[j+1]
} }
@ -289,6 +293,7 @@ type Message struct {
Data map[string]interface{} Data map[string]interface{}
callback func(msg *Message) (sub *Message) callback func(msg *Message) (sub *Message)
freedoms []func(msg *Message) (done bool)
Sessions map[string]*Message Sessions map[string]*Message
messages []*Message messages []*Message
@ -436,6 +441,13 @@ func (m *Message) Format(arg ...interface{}) string {
meta = append(meta, kit.Format(m.code)) meta = append(meta, kit.Format(m.code))
case "ship": case "ship":
meta = append(meta, fmt.Sprintf("%d(%s->%s)", m.code, m.source.Name, m.target.Name)) meta = append(meta, fmt.Sprintf("%d(%s->%s)", m.code, m.source.Name, m.target.Name))
case "source":
target := m.target
m.target = m.source
meta = append(meta, m.Cap("module"))
m.target = target
case "target":
meta = append(meta, m.Cap("module"))
case "detail": case "detail":
meta = append(meta, fmt.Sprintf("%v", m.Meta["detail"])) meta = append(meta, fmt.Sprintf("%v", m.Meta["detail"]))
@ -609,18 +621,7 @@ func (m *Message) Has(key ...string) bool {
return false return false
} }
func (m *Message) CopyTo(msg *Message, arg ...string) *Message { func (m *Message) CopyTo(msg *Message, arg ...string) *Message {
if m == msg {
return m
}
if len(arg) == 0 {
if msg.Hand {
msg.Copy(m, "append").Copy(m, "result")
} else {
msg.Copy(m, "option")
}
} else {
msg.Copy(m, arg...) msg.Copy(m, arg...)
}
return m return m
} }
func (m *Message) Copy(msg *Message, arg ...string) *Message { func (m *Message) Copy(msg *Message, arg ...string) *Message {
@ -629,7 +630,7 @@ func (m *Message) Copy(msg *Message, arg ...string) *Message {
} }
if len(arg) == 0 { if len(arg) == 0 {
if msg.Hand { if msg.Hand {
arg = append(arg, "append") arg = append(arg, "append", "result")
} else { } else {
arg = append(arg, "option") arg = append(arg, "option")
} }
@ -1010,6 +1011,9 @@ func (m *Message) Parse(arg interface{}) string {
} }
func (m *Message) Find(name string, root ...bool) *Message { func (m *Message) Find(name string, root ...bool) *Message {
if name == "" {
return m.Spawn()
}
target := m.target.root target := m.target.root
if len(root) > 0 && !root[0] { if len(root) > 0 && !root[0] {
target = m.target target = m.target
@ -1118,10 +1122,17 @@ func (m *Message) Sess(key string, arg ...interface{}) *Message {
return nil return nil
} }
func (m *Message) Match(key string, spawn bool, hand func(m *Message, s *Context, c *Context, key string) bool) *Message { func (m *Message) Match(key string, spawn bool, hand func(m *Message, s *Context, c *Context, key string) bool) *Message {
if m == nil {
return m
}
if strings.Contains(key, ".") { if strings.Contains(key, ".") {
arg := strings.Split(key, ".") arg := strings.Split(key, ".")
m, key = m.Sess(arg[0], spawn), arg[1] m, key = m.Sess(arg[0], spawn), arg[1]
} }
if m == nil {
return m
}
context := []*Context{m.target} context := []*Context{m.target}
for _, v := range []string{"aaa", "cli"} { for _, v := range []string{"aaa", "cli"} {
@ -1141,26 +1152,41 @@ func (m *Message) Match(key string, spawn bool, hand func(m *Message, s *Context
return m return m
} }
func (m *Message) Call(cb func(msg *Message) (sub *Message), arg ...interface{}) *Message { func (m *Message) Call(cb func(msg *Message) (sub *Message), arg ...interface{}) *Message {
if m == nil {
return m
}
if m.callback = cb; len(arg) > 0 || len(m.Meta["detail"]) > 0 { if m.callback = cb; len(arg) > 0 || len(m.Meta["detail"]) > 0 {
m.Log("call", m.Format("detail", "option"))
m.Cmd(arg...) m.Cmd(arg...)
} }
return m return m
} }
func (m *Message) Back(msg *Message) *Message { func (m *Message) Back(ms ...*Message) *Message {
if msg == nil || m.callback == nil { if m.callback == nil {
return m return m
} }
if len(ms) == 0 {
ms = append(ms, m.Spawn(m.source).Copy(m, "append").Copy(m, "result"))
}
ns := []*Message{}
for _, msg := range ms {
if msg.Hand { if msg.Hand {
m.Log("cbs", msg.Format("ship", "result", "append")) m.Log("back", msg.Format("ship", "result", "append"))
} else { } else {
m.Log("cbs", msg.Format("ship", "detail", "option")) m.Log("back", msg.Format("ship", "detail", "option"))
} }
if sub := m.callback(msg); sub != nil && m.message != nil && m.message != m { if sub := m.callback(msg); sub != nil && m.message != nil && m.message != m {
m.message.Back(sub) ns = append(ns, sub)
}
} }
if len(ns) > 0 {
m.message.Back(ns...)
}
return m return m
} }
func (m *Message) Backs(msg *Message) *Message { func (m *Message) Backs(msg *Message) *Message {
@ -1172,15 +1198,32 @@ func (m *Message) CallBack(sync bool, cb func(msg *Message) (sub *Message), arg
return m.Call(cb, arg...) return m.Call(cb, arg...)
} }
wait := make(chan *Message) wait := make(chan *Message, 10)
go m.Call(func(sub *Message) *Message { go m.Call(func(sub *Message) *Message {
msg := cb(sub) msg := cb(sub)
m.Log("sync", m.Format("done", "result", "append"))
wait <- m wait <- m
return msg return msg
}, arg...) }, arg...)
m.Log("sync", m.Format("wait", "result", "append"))
return <-wait return <-wait
} }
func (m *Message) Free(cbs ...func(msg *Message) (done bool)) *Message {
if len(cbs) == 0 {
for i := len(m.freedoms) - 1; i >= 0; i-- {
m.Log("free", "%d/%d", i, len(m.freedoms)-1)
if !m.freedoms[i](m) {
break
}
m.freedoms = m.freedoms[:i]
}
return m
}
m.freedoms = append(m.freedoms, cbs...)
return m
}
func (m *Message) Assert(e interface{}, msg ...string) bool { func (m *Message) Assert(e interface{}, msg ...string) bool {
switch v := e.(type) { switch v := e.(type) {
@ -1204,7 +1247,7 @@ func (m *Message) Assert(e interface{}, msg ...string) bool {
} }
m.Log("error", "%v", e) m.Log("error", "%v", e)
panic(m.Set("result", "error: ", kit.Format(e), "\n")) panic(e)
} }
func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) *Message { func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) *Message {
defer func() { defer func() {
@ -1236,6 +1279,9 @@ func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message))
func (m *Message) Start(name string, help string, arg ...string) bool { func (m *Message) Start(name string, help string, arg ...string) bool {
return m.Set("detail", arg).target.Spawn(m, name, help).Begin(m).Start(m) return m.Set("detail", arg).target.Spawn(m, name, help).Begin(m).Start(m)
} }
func (m *Message) Close(arg ...string) bool {
return m.Target().Close(m, arg...)
}
func (m *Message) Wait() bool { func (m *Message) Wait() bool {
if m.target.exit != nil { if m.target.exit != nil {
return <-m.target.exit return <-m.target.exit
@ -1523,7 +1569,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
"list_help": &Config{Name: "list_help", Value: "list command", Help: "命令列表帮助"}, "list_help": &Config{Name: "list_help", Value: "list command", Help: "命令列表帮助"},
"table_compact": &Config{Name: "table_compact", Value: "false", Help: "命令列表帮助"}, "table_compact": &Config{Name: "table_compact", Value: "false", Help: "命令列表帮助"},
"table_col_sep": &Config{Name: "table_col_sep", Value: "\t", Help: "命令列表帮助"}, "table_col_sep": &Config{Name: "table_col_sep", Value: " ", Help: "命令列表帮助"},
"table_row_sep": &Config{Name: "table_row_sep", Value: "\n", Help: "命令列表帮助"}, "table_row_sep": &Config{Name: "table_row_sep", Value: "\n", Help: "命令列表帮助"},
"table_space": &Config{Name: "table_space", Value: " ", Help: "命令列表帮助"}, "table_space": &Config{Name: "table_space", Value: " ", Help: "命令列表帮助"},
@ -1701,29 +1747,28 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
} }
} }
if len(arg) > 0 { if len(arg) == 0 {
switch arg[0] {
case "time", "code", "ship", "full", "chain", "stack":
m.Echo(m.Format(arg[0]))
return
}
}
if len(arg) > 0 && arg[0] == "spawn" {
sub := msg.Spawn()
m.Echo("%d", sub.code)
return
}
if len(arg) > 0 {
msg = msg.Spawn().Cmd(arg)
m.Copy(msg, "append").Copy(msg, "result")
return
}
m.Format("summary", msg, "deep") m.Format("summary", msg, "deep")
msg.CopyTo(m) msg.CopyTo(m)
return return
}
switch arg[0] {
case "time", "code", "ship", "full", "chain", "stack":
m.Echo(msg.Format(arg[0]))
case "spawn":
sub := msg.Spawn()
m.Echo("%d", sub.code)
case "call":
case "back":
msg.Back(m)
case "free":
msg.Free()
default:
msg = msg.Spawn().Cmd(arg)
m.Copy(msg, "append").Copy(msg, "result")
}
return
}}, }},
"detail": &Command{Name: "detail [index] [value...]", Help: "查看或添加参数", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { "detail": &Command{Name: "detail [index] [value...]", Help: "查看或添加参数", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
msg := m.message msg := m.message
@ -2343,6 +2388,8 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
}) })
m.Sort("key", "str").Table() m.Sort("key", "str").Table()
return return
case 1:
m.Echo(m.Cap(arg[0]))
case 2: case 2:
if arg[0] == "delete" { if arg[0] == "delete" {
delete(m.target.Caches, arg[1]) delete(m.target.Caches, arg[1])

View File

@ -110,7 +110,7 @@ var Index = &ctx.Context{Name: "gdb", Help: "调试中心",
"start": map[string]interface{}{"value": map[string]interface{}{"enable": false}}, "start": map[string]interface{}{"value": map[string]interface{}{"enable": false}},
}, },
"command": map[string]interface{}{"value": map[string]interface{}{"enable": false}, "command": map[string]interface{}{"value": map[string]interface{}{"enable": false},
"demo": map[string]interface{}{"value": map[string]interface{}{"enable": true}}, "shit": map[string]interface{}{"value": map[string]interface{}{"enable": true}},
}, },
"config": map[string]interface{}{"value": map[string]interface{}{"enable": true}}, "config": map[string]interface{}{"value": map[string]interface{}{"enable": true}},
"cache": map[string]interface{}{"value": map[string]interface{}{"enable": false}, "cache": map[string]interface{}{"value": map[string]interface{}{"enable": false},

View File

@ -125,7 +125,7 @@ var Index = &ctx.Context{Name: "log", Help: "日志中心",
"trace": map[string]interface{}{"value": map[string]interface{}{"file": "error.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[32m", "color_end": "\033[0m"}}, "trace": map[string]interface{}{"value": map[string]interface{}{"file": "error.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[32m", "color_end": "\033[0m"}},
"debug": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}}, "debug": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}},
"search": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}}, "search": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}},
"cbs": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}}, "cbs": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}}},
"bench": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}}}, "bench": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}}},
"begin": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}}, "begin": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},

View File

@ -31,6 +31,7 @@ type NFS struct {
out *os.File out *os.File
send chan *ctx.Message send chan *ctx.Message
echo chan *ctx.Message
hand map[int]*ctx.Message hand map[int]*ctx.Message
*ctx.Context *ctx.Context
@ -644,9 +645,16 @@ func (nfs *NFS) shadow(args ...interface{}) *NFS {
func (nfs *NFS) Send(meta string, arg ...interface{}) *NFS { func (nfs *NFS) Send(meta string, arg ...interface{}) *NFS {
m := nfs.Context.Message() m := nfs.Context.Message()
n, e := fmt.Fprintf(nfs.io, "%s: %s\n", url.QueryEscape(meta), url.QueryEscape(kit.Format(arg[0]))) line := "\n"
if meta != "" {
line = fmt.Sprintf("%s: %s\n", url.QueryEscape(meta), url.QueryEscape(kit.Format(arg[0])))
}
n, e := fmt.Fprint(nfs.io, line)
m.Assert(e) m.Assert(e)
m.Capi("nwrite", n) m.Capi("nwrite", n)
m.Log("send", "%d [%s]", len(line), line)
return nfs return nfs
} }
func (nfs *NFS) Recv(line string) (field string, value string) { func (nfs *NFS) Recv(line string) (field string, value string) {
@ -661,6 +669,9 @@ func (nfs *NFS) Recv(line string) (field string, value string) {
if len(word) == 1 { if len(word) == 1 {
return return
} }
if len(word[1]) == 0 {
return
}
value, e = url.QueryUnescape(word[1]) value, e = url.QueryUnescape(word[1])
m.Assert(e) m.Assert(e)
@ -765,18 +776,18 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
m.Cap("stream", m.Option("ms_source")) m.Cap("stream", m.Option("ms_source"))
nfs.io = m.Optionv("io").(io.ReadWriter) nfs.io = m.Optionv("io").(io.ReadWriter)
nfs.send = make(chan *ctx.Message, 10) nfs.send = make(chan *ctx.Message, 10)
nfs.echo = make(chan *ctx.Message, 10)
nfs.hand = map[int]*ctx.Message{} nfs.hand = map[int]*ctx.Message{}
go func() { //发送消息队列 go func() { //发送消息队列
for { for {
msg, code, meta, body := m, 0, "detail", "option"
select { select {
case msg := <-nfs.send: case msg = <-nfs.send:
code, meta, body := "0", "detail", "option" code = msg.Code()
if msg.Options("remote_code") { // 发送响应 nfs.hand[code] = msg
code, meta, body = msg.Option("remote_code"), "result", "append" case msg = <-nfs.echo:
} else { // 发送请求 code, meta, body = msg.Optioni("remote_code"), "result", "append"
code = kit.Format(m.Capi("nsend", 1))
nfs.hand[kit.Int(code)] = msg
} }
nfs.Send("code", code) nfs.Send("code", code)
@ -788,7 +799,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
nfs.Send(k, v) nfs.Send(k, v)
} }
} }
} nfs.Send("")
} }
}() }()
@ -796,6 +807,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
msg, code, head, body := m, "0", "result", "append" msg, code, head, body := m, "0", "result", "append"
for bio := bufio.NewScanner(nfs.io); bio.Scan(); { for bio := bufio.NewScanner(nfs.io); bio.Scan(); {
m.TryCatch(m, true, func(m *ctx.Message) {
switch field, value := nfs.Recv(bio.Text()); field { switch field, value := nfs.Recv(bio.Text()); field {
case "code": case "code":
msg, code = m.Sess("ms_target"), value msg, code = m.Sess("ms_target"), value
@ -811,9 +823,10 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
case "": case "":
if head == "detail" { // 接收请求 if head == "detail" { // 接收请求
msg.Detail(-1, "remote")
msg.Option("remote_code", code) msg.Option("remote_code", code)
msg.Call(func(sub *ctx.Message) *ctx.Message { msg.Call(func(msg *ctx.Message) *ctx.Message {
nfs.send <- msg.Copy(sub, "append").Copy(sub, "result") nfs.echo <- msg
return nil return nil
}) })
} else { // 接收响应 } else { // 接收响应
@ -825,9 +838,16 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
default: default:
msg.Add(body, field, value) msg.Add(body, field, value)
} }
}, func(m *ctx.Message) {
for bio.Scan() {
if text := bio.Text(); text == "" {
break
}
}
})
} }
m.Sess("tcp", false).Close()
return true return true
} }
func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool { func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool {
@ -1252,6 +1272,12 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
} }
return return
}}, }},
"term": &ctx.Command{Name: "term action args...", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
nfs.Term(m, arg[0], arg[1:])
}
return
}},
"action": &ctx.Command{Name: "action cmd", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "action": &ctx.Command{Name: "action cmd", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) { if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
msg := m.Cmd("cli.source", arg) msg := m.Cmd("cli.source", arg)
@ -1264,6 +1290,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
"remote": &ctx.Command{Name: "remote listen|dial args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "remote": &ctx.Command{Name: "remote listen|dial args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { //{{{ if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { //{{{
m.Sess("tcp").Call(func(sub *ctx.Message) *ctx.Message { m.Sess("tcp").Call(func(sub *ctx.Message) *ctx.Message {
sub.Sess("ms_source", sub)
sub.Sess("ms_target", m.Source()) sub.Sess("ms_target", m.Source())
sub.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "远程文件") sub.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "远程文件")
return sub return sub

View File

@ -2,12 +2,15 @@ package ssh
import ( import (
"contexts/ctx" "contexts/ctx"
"encoding/base64"
"fmt"
"os"
"path"
"strings" "strings"
"toolkit" "toolkit"
) )
type SSH struct { type SSH struct {
peer map[string]*ctx.Message
*ctx.Context *ctx.Context
} }
@ -20,270 +23,212 @@ func (ssh *SSH) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
return s return s
} }
func (ssh *SSH) Begin(m *ctx.Message, arg ...string) ctx.Server { func (ssh *SSH) Begin(m *ctx.Message, arg ...string) ctx.Server {
ssh.Caches["hostname"] = &ctx.Cache{Name: "hostname", Value: "", Help: "主机数量"}
return ssh return ssh
} }
func (ssh *SSH) Start(m *ctx.Message, arg ...string) bool { func (ssh *SSH) Start(m *ctx.Message, arg ...string) bool {
m.Cap("stream", m.Source().Name) return true
return false
} }
func (ssh *SSH) Close(m *ctx.Message, arg ...string) bool { func (ssh *SSH) Close(m *ctx.Message, arg ...string) bool {
return false return true
} }
var Index = &ctx.Context{Name: "ssh", Help: "集群中心", var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
Caches: map[string]*ctx.Cache{ Caches: map[string]*ctx.Cache{
"nhost": &ctx.Cache{Name: "主机数量", Value: "0", Help: "主机数量"}, "nhost": &ctx.Cache{Name: "nhost", Value: "0", Help: "主机数量"},
"domain": &ctx.Cache{Name: "domain", Value: "", Help: "主机域名"}, "hostname": &ctx.Cache{Name: "hostname", Value: "shy", Help: "本机域名"},
}, },
Configs: map[string]*ctx.Config{ Configs: map[string]*ctx.Config{
"host": &ctx.Config{Name: "host", Value: map[string]interface{}{}, Help: "主机数量"}, "host": &ctx.Config{Name: "host", Value: map[string]interface{}{}, Help: "主机信息"},
"hostname": &ctx.Config{Name: "hostname", Value: "com", Help: "主机域名"},
"hostname": &ctx.Config{Name: "hostname", Value: "com", Help: "主机数量"}, "current": &ctx.Config{Name: "current", Value: "", Help: "当前主机"},
"timer": &ctx.Config{Name: "timer", Value: "", Help: "当前主机"},
"domain.json": &ctx.Config{Name: "domain.json", Value: "var/domain.json", Help: "主机数量"},
"domain.png": &ctx.Config{Name: "domain.png", Value: "var/domain.png", Help: "主机数量"},
}, },
Commands: map[string]*ctx.Command{ Commands: map[string]*ctx.Command{
"remote": &ctx.Command{Name: "remote listen|dial|send args...", Help: "网络监听", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "remote": &ctx.Command{Name: "remote listen|dial args...", Help: "远程连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 { if len(arg) == 0 {
m.Cmdy("ctx.config", "host") m.Cmdy("ctx.config", "host")
return return
} }
host := m.Confm("host", arg[0]) switch arg[0] {
if host != nil { case "redial":
arg = arg[1:] if !m.Caps("hostname") {
m.Cmdx("remote", "dial", arg[1:])
}
case "listen", "dial":
m.Call(func(nfs *ctx.Message) *ctx.Message {
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(cmd *ctx.Message) *ctx.Message {
m.Cap("stream", nfs.Format("target"))
m.Cap("hostname", cmd.Result(0))
m.Confv("host", cmd.Result(1), map[string]interface{}{
"module": nfs.Format("target"),
"create_time": m.Time(),
"access_time": m.Time(),
})
if !m.Confs("current") {
m.Conf("current", cmd.Result(1))
} }
switch arg[0] { nfs.Free(func(nfs *ctx.Message) bool {
case "listen", "dial": m.Conf("timer", m.Cmdx("cli.timer", "repeat", "10s", "context", "ssh", "remote", "redial", arg[1:]))
m.Call(func(sub *ctx.Message) *ctx.Message {
h, _ := kit.Hash("host", m.Option("ms_source"), "uniq") m.Log("info", "delete host %s", cmd.Result(1))
m.Log("fuck", "what %v", sub.Format()) delete(m.Confm("host"), cmd.Result(1))
m.Confv("host", h, map[string]interface{}{ m.Cap("hostname", "")
"module": sub.Cap("module"), m.Cap("stream", "")
"type": arg[0], return true
}) })
return nil return nil
}, "send", "recv", "add", m.Conf("hostname"))
}
return nil
}, "nfs.remote", arg) }, "nfs.remote", arg)
case "exec": case "recv":
m.Find(kit.Format(host["module"]), true).CallBack(true, func(sub *ctx.Message) *ctx.Message { switch arg[1] {
m.Copy(sub) case "add":
return nil if host := m.Confm("host", arg[2]); host == nil {
}, arg[1:]) m.Confv("host", arg[2], map[string]interface{}{
} "module": m.Format("source"),
"create_time": m.Time(),
return "access_time": m.Time(),
}}, })
} else if len(arg) > 3 && arg[3] == kit.Format(host["token"]) {
"demo": &ctx.Command{Name: "demo", Help: "远程执行", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { host["access_time"] = m.Time()
m.Echo("demo") host["module"] = m.Format("source")
return
}},
"send": &ctx.Command{Name: "send [domain str] cmd arg...", Help: "远程执行", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if ssh, ok := m.Target().Server.(*SSH); m.Assert(ok) {
origin, domain := "", ""
if len(arg) > 1 && arg[0] == "domain" {
origin, arg = arg[1], arg[2:]
if d := strings.TrimPrefix(origin, m.Cap("domain")); len(d) > 0 && d[0] == '.' {
domain = d[1:]
} else if d == "" {
domain = d
} else { } else {
domain = origin arg[2] = fmt.Sprintf("%s_%d", arg[2], m.Capi("nhost", 1))
m.Confv("host", arg[2], map[string]interface{}{
"module": m.Format("source"),
"create_time": m.Time(),
"access_time": m.Time(),
})
}
if !m.Confs("current") {
m.Conf("current", arg[2])
} }
if domain == "" { //本地执行 m.Echo(arg[2]).Echo(m.Cap("hostname")).Back(m)
msg := m.Spawn().Cmd(arg) m.Sess("ms_source", false).Free(func(msg *ctx.Message) bool {
m.Copy(msg, "result").Copy(msg, "append") m.Log("info", "delete host %s", arg[2])
return delete(m.Confm("host"), arg[2])
}
} else {
if m.Has("send_code") { //本地执行
msg := m.Spawn().Cmd(arg)
m.Copy(msg, "result").Copy(msg, "append")
} else { //对端执行
msg := m.Spawn(ssh.Message().Source())
msg.Cmd("send", arg)
m.Copy(msg, "result").Copy(msg, "append")
}
return
}
match := false
host := strings.SplitN(domain, ".", 2)
c.Travel(m, func(m *ctx.Message, i int) bool {
if i == 0 {
return true return true
})
} }
if m.Cap("hostname") == host[0] || "*" == host[0] {
ssh, ok := m.Target().Server.(*SSH)
m.Assert(ok)
msg := m.Spawn(ssh.Message().Source())
if len(host) > 1 { default:
msg.Cmd("send", "domain", host[1], arg) names := strings.SplitN(arg[0], ".", 2)
if names[0] == "" { // 本地执行
host := m.Confm("host", m.Option("hostname"))
msg := m.Find(kit.Format(host["cm_target"])).Cmd(arg[1:])
m.Copy(msg, "append").Copy(msg, "result")
host["cm_target"] = msg.Cap("module")
m.Back(m)
return
}
m.Option("hostname", m.Cap("hostname"))
sync := !m.Options("remote_code") //同步或异步
if arg[1] == "async" {
sync, arg = false, arg[2:]
} else if arg[1] == "sync" {
sync, arg = true, arg[2:]
} else { } else {
msg.Cmd("send", arg) arg = arg[1:]
} }
m.Copy(msg, "result").Copy(msg, "append")
if !match { rest := kit.Select("", names, 1)
match = !m.Appends("domain_miss") if names[0] == "*" {
} m.Confm("host", func(name string, host map[string]interface{}) {
return host[0] == "*" m.Find(kit.Format(host["module"]), true).Copy(m, "option").CallBack(sync, func(sub *ctx.Message) *ctx.Message {
} return m.Copy(sub)
return false }, "send", "", arg)
}) })
if match { } else if m.Confm("host", names[0], func(host map[string]interface{}) {
return m.Find(kit.Format(host["module"]), true).Copy(m, "option").CallBack(sync, func(sub *ctx.Message) *ctx.Message {
} return m.Copy(sub)
if m.Target() == c && m.Has("send_code") { }, "send", rest, arg)
m.Appends("domain_miss", true) m.Log("fuck", "m %v", m.Meta)
return
}
if m.Cap("domain") == m.Conf("hostname") {
m.Appends("domain_miss", true)
return
}
// 向上路由 }) == nil {
msg := m.Spawn(c.Message().Source()) m.Find(m.Cap("stream"), true).Copy(m, "option").CallBack(sync, func(sub *ctx.Message) *ctx.Message {
msg.Cmd("send", "domain", origin, arg) return m.Copy(sub)
m.Copy(msg, "result").Copy(msg, "append") }, "send", strings.Join(names, "."), arg)
}
} }
return return
}}, }},
"sh": &ctx.Command{Name: "sh [[host] name] cmd...", Help: "发送命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
"pwd": &ctx.Command{Name: "pwd [hostname]", Help: "主机域名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 { if len(arg) == 0 {
m.Echo(m.Cap("domain")) m.Echo(m.Conf("current"))
return return
} }
if m.Options("send_code") { if arg[0] == "host" {
if m.Target() == c { m.Conf("current", arg[1])
msg := m.Spawn().Cmd("send", "pwd", m.Confx("hostname", arg, 0)) arg = arg[2:]
m.Cap("hostname", msg.Result(0)) } else if m.Confm("host", arg[0]) != nil {
m.Cap("domain", msg.Result(1)) m.Conf("current", arg[0])
} else { arg = arg[1:]
hostname := arg[0]
c.Travel(m, func(m *ctx.Message, line int) bool {
if hostname == m.Cap("hostname") {
hostname += m.Cap("nhost")
return false
}
return false
})
m.Echo(m.Cap("hostname", hostname))
m.Echo("%s.%s", m.Cap("domain"), m.Cap("hostname"))
}
return
} }
if m.Target() == c { msg := m.Cmd("ssh.remote", m.Conf("current"), arg)
m.Conf("hostname", arg[0]) m.Copy(msg, "result")
msg := m.Spawn().Cmd("send", "pwd", arg[0])
m.Cap("hostname", msg.Result(0))
m.Cap("domain", msg.Result(1))
} else {
m.Spawn().Cmd("send", "pwd", arg[0])
}
m.Echo(m.Cap("domain"))
return return
}}, }},
"hello": &ctx.Command{Name: "hello request", Help: "加密请求", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "cp": &ctx.Command{Name: "cp [[host] name] filename", Help: "发送文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
aaa := m.Target().Message().Sess("aaa", false)
for _, k := range m.Meta["seal"] {
for i, v := range m.Meta[k] {
m.Meta[k][i] = m.Spawn(aaa).Cmd("deal", v).Result(0)
}
}
for _, k := range m.Meta["encrypt"] {
for i, v := range m.Meta[k] {
m.Meta[k][i] = m.Spawn(aaa).Cmd("decrypt", v).Result(0)
}
}
if len(arg) == 0 { if len(arg) == 0 {
if !m.Has("mi") { m.Echo(m.Conf("current"))
cert := aaa.Spawn().Cmd("certificate")
m.Echo(cert.Result(0))
} else {
msg := m.Sess("aaa").Cmd("login", m.Option("mi"), m.Option("mi"))
m.Echo(msg.Result(0))
msg.Sess("aaa").Cmd("newcipher", m.Option("mi"))
}
return return
} }
msg := m.Spawn().Copy(m, "option").Cmd(arg) if arg[0] == "host" {
m.Copy(msg, "result").Copy(msg, "append") m.Conf("current", arg[1])
arg = arg[2:]
return } else if m.Confm("host", arg[0]) != nil {
}}, m.Conf("current", arg[0])
"shake": &ctx.Command{ arg = arg[1:]
Name: "shake [domain host] cmd... [seal option...][encrypt option...]",
Help: "加密通信",
Form: map[string]int{"seal": -1, "encrypt": -1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if ssh, ok := m.Target().Server.(*SSH); m.Assert(ok) {
if len(arg) == 0 {
for k, v := range ssh.peer {
m.Echo("%s: %s\n", k, v.Cap("stream"))
}
return
} }
peer := "peer" if arg[0] == "save" {
args := []string{} buf, e := base64.StdEncoding.DecodeString(m.Option("filebuf"))
if len(arg) > 1 && arg[0] == "domain" { m.Assert(e)
args = append(args, "domain", arg[1])
peer, arg = arg[1], arg[2:]
}
if ssh.peer == nil {
ssh.peer = map[string]*ctx.Message{}
}
user, ok := ssh.peer[peer]
if !ok {
user = m.Sess("aaa").Cmd("login", "cert", m.Spawn().Cmd("send", args, "hello"), peer)
ssh.peer[peer] = user
mi := user.Cap("sessid")
remote := m.Spawn().Add("option", mi, m.Spawn(user).Cmd("seal", mi)).Add("option", "seal", mi).Cmd("send", args, "hello") f, e := os.OpenFile(path.Join("tmp", m.Option("filename")), os.O_RDWR|os.O_CREATE, 0666)
m.Spawn(user).Cmd("newcipher", mi) f.WriteAt(buf, int64(m.Optioni("filepos")))
user.Cap("remote", "remote", remote.Result(0), "远程会话") return e
user.Cap("remote_mi", "remote_mi", mi, "远程密钥")
} }
msg := m.Spawn(ssh.Message().Source()).Copy(m, "option") p := m.Cmdx("nfs.path", arg[0])
msg.Option("hello", "world") f, e := os.Open(p)
msg.Option("world", "hello") m.Assert(e)
for _, k := range msg.Meta["seal"] { s, e := f.Stat()
for i, v := range msg.Meta[k] { m.Assert(e)
msg.Meta[k][i] = msg.Spawn(user).Cmd("seal", v).Result(0)
buf := make([]byte, 1024)
for i := int64(0); i < s.Size(); i += 1024 {
n, _ := f.ReadAt(buf, i)
if n == 0 {
break
} }
buf = buf[:n]
msg := m.Spawn()
msg.Option("filename", arg[0])
msg.Option("filesize", s.Size())
msg.Option("filepos", i)
msg.Option("filebuf", base64.StdEncoding.EncodeToString(buf))
msg.Cmd("remote", m.Conf("current"), "cp", "save", arg[0])
} }
for _, k := range msg.Meta["encrypt"] {
for i, v := range msg.Meta[k] {
msg.Meta[k][i] = msg.Spawn(user).Cmd("encrypt", v).Result(0)
}
}
msg.Detail("send", args, "hello", arg)
ssh.Message().Back(msg)
m.Copy(msg, "result").Copy(msg, "append")
}
return
}},
"save": &ctx.Command{Name: "save", Help: "远程执行", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
json := m.Sess("nfs")
json.Put("option", "data", map[string]string{"domain": m.Cap("domain")})
json.Cmd("json", m.Conf("domain.json"))
m.Sess("nfs").Cmd("genqr", m.Conf("domain.png"), json.Result(0))
return return
}}, }},
}, },

View File

@ -79,8 +79,9 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool {
m.Log("info", "%s dial %s", m.Cap("nclient"), m.Log("info", "%s dial %s", m.Cap("nclient"),
m.Cap("stream", fmt.Sprintf("%s->%s", tcp.LocalAddr(), tcp.RemoteAddr()))) m.Cap("stream", fmt.Sprintf("%s->%s", tcp.LocalAddr(), tcp.RemoteAddr())))
m.Sess("tcp", m)
m.Option("ms_source", tcp.Context.Name) m.Option("ms_source", tcp.Context.Name)
m.Put("option", "io", tcp).Back(m.Spawn(m.Source())) m.Put("option", "io", tcp).Back()
return false return false
case "accept": case "accept":
@ -91,8 +92,9 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool {
m.Log("info", "%s accept %s", m.Cap("nclient"), m.Log("info", "%s accept %s", m.Cap("nclient"),
m.Cap("stream", fmt.Sprintf("%s<-%s", tcp.LocalAddr(), tcp.RemoteAddr()))) m.Cap("stream", fmt.Sprintf("%s<-%s", tcp.LocalAddr(), tcp.RemoteAddr())))
m.Sess("tcp", m)
m.Option("ms_source", tcp.Context.Name) m.Option("ms_source", tcp.Context.Name)
m.Put("option", "io", tcp).Back(m.Spawn(m.Source())) m.Put("option", "io", tcp).Back()
return false return false
case "listen": case "listen":
@ -118,8 +120,8 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool {
for { for {
c, e := tcp.Accept() c, e := tcp.Accept()
m.Assert(e) m.Assert(e)
m.Spawn(Index).Put("option", "io", c).Call(func(com *ctx.Message) *ctx.Message { m.Spawn(Index).Put("option", "io", c).Call(func(sub *ctx.Message) *ctx.Message {
return com.Spawn(m.Source()) return sub.Spawn(m.Source())
}, "accept", c.RemoteAddr().String(), m.Cap("security"), m.Cap("protocol")) }, "accept", c.RemoteAddr().String(), m.Cap("security"), m.Cap("protocol"))
} }