From debceb6c0f0ab00affc00248e3cfa5101275b844 Mon Sep 17 00:00:00 2001 From: shaoying Date: Thu, 14 Dec 2017 23:48:24 +0800 Subject: [PATCH 1/4] =?UTF-8?q?mac=20mod=20context.close=20=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E4=BA=86=E6=A8=A1=E5=9D=97=E7=9A=84=E9=80=80=E5=87=BA?= =?UTF-8?q?=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/context/aaa/aaa.go | 24 +++++++++++++----- src/context/cli/cli.go | 16 +++++++++++- src/context/ctx.go | 55 ++++++++++++++++++++++-------------------- src/context/ssh/ssh.go | 2 +- src/example/bench.go | 4 +-- 5 files changed, 65 insertions(+), 36 deletions(-) diff --git a/src/context/aaa/aaa.go b/src/context/aaa/aaa.go index 98f33b97..7000443b 100644 --- a/src/context/aaa/aaa.go +++ b/src/context/aaa/aaa.go @@ -44,7 +44,7 @@ func (aaa *AAA) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ if len(arg) > 0 { // {{{ bs := md5.Sum([]byte(fmt.Sprintln("用户密码:%s", arg[0]))) m.Assert(x.Value == "" || x.Value == hex.EncodeToString(bs[:]), "密码错误") - m.Cap("expire", fmt.Sprintf("%d", time.Now().Unix()+int64(m.Confi("expire")))) + m.Cap("expire", fmt.Sprintf("%d", time.Now().Unix()+int64(Pulse.Confi("expire")))) return hex.EncodeToString(bs[:]) } return x.Value @@ -77,11 +77,12 @@ func (aaa *AAA) Start(m *ctx.Message, arg ...string) bool { // {{{ if len(arg) > 1 { if m.Cap("sessid") == "" { m.Cap("sessid", aaa.session(arg[1])) - m.Capi("nuser", 1) + Pulse.Capi("nuser", 1) } - m.Log("info", m.Source, "login %s %s", m.Cap("group", arg[0]), m.Cap("username", arg[1])) + m.Log("info", m.Source, "create %s %s", m.Cap("group", arg[0]), m.Cap("username", arg[1])) m.Cap("stream", m.Cap("username")) } + m.Log("info", m.Source, "login %s %s", m.Cap("group"), m.Cap("username")) return false } @@ -94,15 +95,18 @@ func (aaa *AAA) Close(m *ctx.Message, arg ...string) bool { // {{{ switch aaa.Context { case m.Target: + if len(aaa.Context.Requests) == 0 { + m.Log("info", nil, "%d logout %s", Pulse.Capi("nuser", -1)+1, m.Cap("username")) + } case m.Source: } - m.Log("info", nil, "%d logout %s", Pulse.Capi("nuser", -1)+1, m.Cap("username")) return true } // }}} +var Pulse *ctx.Message var Index = &ctx.Context{Name: "aaa", Help: "认证中心", Caches: map[string]*ctx.Cache{ "nuser": &ctx.Cache{Name: "用户数量", Value: "0", Help: "用户数量"}, @@ -131,6 +135,10 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", m.Source.Group, m.Source.Owner = m.Cap("group"), m.Target m.Log("info", m.Source, "logon %s", m.Cap("group"), m.Cap("username")) + if m.Name != "" { + c.Requests = append(c.Requests, m) + m.Index = len(m.Target.Requests) + } return m.Cap("username") } case 2, 3: @@ -139,12 +147,17 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", username, password = arg[1], arg[2] } - if username == m.Conf("rootname") { + if username == Pulse.Conf("rootname") { m.Set("detail", group, username).Target.Start(m) } else if msg := m.Find(username); msg == nil { m.Start(username, "认证用户", group, username) } else { m.Target = msg.Target + msg.Target.Start(msg) + if m.Name != "" { + m.Target.Requests = append(m.Target.Requests, m) + m.Index = len(m.Target.Requests) + } } m.Cap("password", password) @@ -162,7 +175,6 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", }, }, } -var Pulse *ctx.Message func init() { aaa := &AAA{} diff --git a/src/context/cli/cli.go b/src/context/cli/cli.go index b9f8c467..f7efb908 100644 --- a/src/context/cli/cli.go +++ b/src/context/cli/cli.go @@ -239,6 +239,9 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ if cli.Context != Index { cli.Owner = nil } + if cli.Context == Index { + Pulse = m + } cli.target = cli.Context cli.alias = map[string]string{ @@ -286,6 +289,7 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ cli.echo("password>") fmt.Fscanln(cli.in, &password) + msg.Name = "aaa" msg.Wait = make(chan bool) if msg.Cmd("login", username, password) == "" { cli.echo("登录失败") @@ -299,7 +303,6 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ cli.Sessions = make(map[string]*ctx.Message) } cli.Sessions["aaa"] = msg - msg.Name = "aaa" } } else { m.Cap("stream", "stdout") @@ -358,7 +361,17 @@ func (cli *CLI) Close(m *ctx.Message, arg ...string) bool { // {{{ switch cli.Context { case m.Target: + if len(cli.Context.Requests) == 0 { + m.Log("info", nil, "%s close %v", Pulse.Cap("nterm"), arg) + } case m.Source: + if m.Name == "aaa" { + msg := m.Spawn(cli.Context) + msg.Master = cli.Context + if !cli.Context.Close(msg, arg...) { + return false + } + } } return true @@ -366,6 +379,7 @@ func (cli *CLI) Close(m *ctx.Message, arg ...string) bool { // {{{ // }}} +var Pulse *ctx.Message var Index = &ctx.Context{Name: "cli", Help: "管理中心", Caches: map[string]*ctx.Cache{ "nterm": &ctx.Cache{Name: "终端数量", Value: "0", Help: "已经运行的终端数量"}, diff --git a/src/context/ctx.go b/src/context/ctx.go index 4c1e871f..41a53f89 100644 --- a/src/context/ctx.go +++ b/src/context/ctx.go @@ -72,7 +72,6 @@ type Context struct { Owner *Context Group string - Pulse *Message Server } @@ -127,8 +126,9 @@ func (c *Context) Begin(m *Message) *Context { // {{{ } } - c.Requests = []*Message{m} + m.Index = 1 c.Historys = []*Message{m} + c.Requests = []*Message{m} if c.Server != nil { c.Server.Begin(m, m.Meta["detail"]...) @@ -161,12 +161,24 @@ func (c *Context) Start(m *Message) bool { // {{{ // }}} func (c *Context) Close(m *Message, arg ...string) bool { // {{{ m.Log("close", c, "close %v", arg) + if m.Target == c { - for k, v := range c.Sessions { - delete(c.Sessions, k) - if v.Target != c && !v.Target.Close(v, arg...) { - return false + switch { + case m.Index == 0: + for i := len(c.Requests) - 1; i >= 0; i-- { + v := c.Requests[i] + v.Index = -1 + if v.Source != c && !v.Source.Close(v, arg...) { + v.Index = i + return false + } + c.Requests = c.Requests[:i] } + case m.Index > 0: + for i := m.Index - 1; i < len(c.Requests)-1; i++ { + c.Requests[i] = c.Requests[i+1] + } + c.Requests = c.Requests[:len(c.Requests)-1] } } @@ -174,34 +186,26 @@ func (c *Context) Close(m *Message, arg ...string) bool { // {{{ return false } - if m.Source == c { + if m.Source == c && m.Target != c { if _, ok := c.Sessions[m.Name]; ok { delete(c.Sessions, m.Name) - m.Target.Server.Close(m, arg...) } - } else { - if m.Index == -1 { - return true - } - } - - if len(c.Sessions) > 0 { - return false - } - - if m.Cap("status") == "close" { return true } + if len(c.Requests) > 0 { + return false + } + + m.Log(m.Cap("status", "close"), c, "%d server %v", m.root.Capi("nserver", -1)+1, arg) if c.context != nil && len(c.contexts) == 0 { m.Log("close", c, "%d context %v", m.root.Capi("ncontext", -1)+1, arg) delete(c.context.contexts, c.Name) } - for _, v := range c.Requests { - if v.Source != c && v.Index != -1 { - v.Index = -1 - v.Source.Close(v, arg...) + for _, v := range c.Sessions { + if v.Target != c { + v.Target.Close(v, arg...) } } @@ -1077,7 +1081,8 @@ func (m *Message) Cap(key string, arg ...string) string { // {{{ // }}} -var Index = &Context{Name: "ctx", Help: "元始模块", +var Pulse = &Message{code: 0, time: time.Now(), Wait: make(chan bool), Source: Index, Master: Index, Target: Index} +var Index = &Context{Name: "ctx", Help: "模块中心", Caches: map[string]*Cache{ "nserver": &Cache{Name: "服务数量", Value: "0", Help: "显示已经启动运行模块的数量"}, "ncontext": &Cache{Name: "模块数量", Value: "0", Help: "显示功能树已经注册模块的数量"}, @@ -1562,8 +1567,6 @@ var Index = &Context{Name: "ctx", Help: "元始模块", }, } -var Pulse = &Message{code: 0, time: time.Now(), Wait: make(chan bool), Source: Index, Master: Index, Target: Index} - func init() { Pulse.root = Pulse Index.root = Index diff --git a/src/context/ssh/ssh.go b/src/context/ssh/ssh.go index 174ad3a6..201100a2 100644 --- a/src/context/ssh/ssh.go +++ b/src/context/ssh/ssh.go @@ -30,7 +30,7 @@ func (ssh *SSH) Close(m *ctx.Message, arg ...string) bool { return false } -var Index = &ctx.Context{Name: "ssh", Help: "加密终端", +var Index = &ctx.Context{Name: "ssh", Help: "集群中心", Caches: map[string]*ctx.Cache{}, Configs: map[string]*ctx.Config{}, Commands: map[string]*ctx.Command{}, diff --git a/src/example/bench.go b/src/example/bench.go index e8f8ee84..38e9ed1d 100644 --- a/src/example/bench.go +++ b/src/example/bench.go @@ -4,13 +4,13 @@ import ( "context" _ "context/aaa" _ "context/cli" + _ "context/ssh" _ "context/mdb" + _ "context/nfs" _ "context/tcp" _ "context/web" - _ "context/ssh" - _ "context/lex" "os" From 8f4d2302d6a41da9e1a29e9763dd57bb97c8be6f Mon Sep 17 00:00:00 2001 From: shaoying Date: Mon, 18 Dec 2017 00:11:45 +0800 Subject: [PATCH 2/4] =?UTF-8?q?mac=20add=20ssh=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=BA=86=E9=9B=86=E7=BE=A4=E4=B8=AD=E5=BF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- etc/go.snippets | 15 ++++- etc/init.sh | 20 +++--- src/context/aaa/aaa.go | 8 +-- src/context/cli/cli.go | 8 +-- src/context/ctx.go | 84 ++++++++++++------------- src/context/ssh/ssh.go | 136 +++++++++++++++++++++++++++++++++++++---- 6 files changed, 198 insertions(+), 73 deletions(-) diff --git a/etc/go.snippets b/etc/go.snippets index c8452b87..9cdde01e 100644 --- a/etc/go.snippets +++ b/etc/go.snippets @@ -39,6 +39,9 @@ snippet c } func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Begin(m *ctx.Message, arg ...string) ctx.Server { + if `Filename()`.Context == Index { + Pulse = m + } return `Filename()` } @@ -46,11 +49,20 @@ snippet c return false } - func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Exit(m *ctx.Message, arg ...string) bool { + func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Close(m *ctx.Message, arg ...string) bool { + switch `Filename()`.Context { + case m.Target: + if `Filename()`.Context == Index { + return false + } + case m.Source: + return true + } return false } + var Pulse *ctx.Message var Index = &ctx.Context{Name: "`Filename()`", Help: "${1}", Caches: map[string]*ctx.Cache{}, Configs: map[string]*ctx.Config{}, @@ -67,6 +79,7 @@ snippet cmd ${4} return "" }}, + snippet conf "${1}": &ctx.Config{Name: "${2}", Value: "${3}", Help: "${4}", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { if len(arg) > 0 { diff --git a/etc/init.sh b/etc/init.sh index 9f7bdbc2..e2ca999f 100644 --- a/etc/init.sh +++ b/etc/init.sh @@ -1,13 +1,19 @@ -# ~lex source etc/lex.sh -~cli @lex lex -~root aaa login root root -# ~tcp listen ":9393" +~cli + @lex lex + +~aaa + login root root + +~tcp + listen :9393 + # ~tcp dial ":9393" -~cli remote slaver listen ":9393" tcp +# ~cli remote slaver listen ":9393" tcp # @debug on -~mdb open chat chat "chat:chat@/chat" mysql -~web listen +# ~mdb open chat chat "chat:chat@/chat" mysql +# ~web listen +# ~ssh listen :9898 return diff --git a/src/context/aaa/aaa.go b/src/context/aaa/aaa.go index 7000443b..ba9f5a7b 100644 --- a/src/context/aaa/aaa.go +++ b/src/context/aaa/aaa.go @@ -89,12 +89,12 @@ func (aaa *AAA) Start(m *ctx.Message, arg ...string) bool { // {{{ // }}} func (aaa *AAA) Close(m *ctx.Message, arg ...string) bool { // {{{ - if aaa.Context == Index { - return false - } - switch aaa.Context { case m.Target: + if aaa.Context == Index { + return false + } + if len(aaa.Context.Requests) == 0 { m.Log("info", nil, "%d logout %s", Pulse.Capi("nuser", -1)+1, m.Cap("username")) } diff --git a/src/context/cli/cli.go b/src/context/cli/cli.go index f7efb908..b4695538 100644 --- a/src/context/cli/cli.go +++ b/src/context/cli/cli.go @@ -355,12 +355,12 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ // }}} func (cli *CLI) Close(m *ctx.Message, arg ...string) bool { // {{{ - if cli.Context == Index { - return false - } - switch cli.Context { case m.Target: + if cli.Context == Index { + return false + } + if len(cli.Context.Requests) == 0 { m.Log("info", nil, "%s close %v", Pulse.Cap("nterm"), arg) } diff --git a/src/context/ctx.go b/src/context/ctx.go index 41a53f89..0b14dca8 100644 --- a/src/context/ctx.go +++ b/src/context/ctx.go @@ -55,17 +55,17 @@ type Context struct { Configs map[string]*Config Commands map[string]*Command - contexts map[string]*Context - context *Context root *Context + context *Context + contexts map[string]*Context - Sessions map[string]*Message - Historys []*Message - Requests []*Message - - messages chan *Message - message *Message Master *Context + messages chan *Message + + Pulse *Message + Requests []*Message + Historys []*Message + Sessions map[string]*Message Index map[string]*Context Groups map[string]*Context @@ -86,24 +86,20 @@ func (c *Context) Register(s *Context, x Server) *Context { // {{{ c.contexts[s.Name] = s s.context = c s.Server = x - - if c.root != nil { - s.root = c.root - } return s } // }}} func (c *Context) Spawn(m *Message, name string, help string) *Context { // {{{ - s := &Context{Name: name, Help: help, context: c} + s := &Context{Name: name, Help: help, root: c.root, context: c} - if c.Server != nil { + if m.Target = s; c.Server != nil { c.Register(s, c.Server.Spawn(m, s, m.Meta["detail"]...)) } else { c.Register(s, nil) } - if m.Target = s; m.Template != nil { + if m.Template != nil { m.Template.Source = s } @@ -115,21 +111,22 @@ func (c *Context) Begin(m *Message) *Context { // {{{ c.Caches["status"] = &Cache{Name: "服务状态(begin/start/close)", Value: "begin", Help: "服务状态,begin:初始完成,start:正在运行,close:未在运行"} c.Caches["stream"] = &Cache{Name: "服务数据", Value: "", Help: "服务数据"} + m.Index = 1 + c.Pulse = m + c.Requests = []*Message{m} + c.Historys = []*Message{m} + c.Master = m.Master.Master c.Owner = m.Master.Owner c.Group = m.Master.Group - m.Log("begin", nil, "%d %v", m.Capi("ncontext", 1), m.Meta["detail"]) + m.Log("begin", nil, "%d context %v", m.Capi("ncontext", 1), m.Meta["detail"]) for k, x := range c.Configs { if x.Hand != nil { m.Conf(k, x.Value) } } - m.Index = 1 - c.Historys = []*Message{m} - c.Requests = []*Message{m} - if c.Server != nil { c.Server.Begin(m, m.Meta["detail"]...) } @@ -139,42 +136,35 @@ func (c *Context) Begin(m *Message) *Context { // {{{ // }}} func (c *Context) Start(m *Message) bool { // {{{ - if m.Cap("status") != "start" && c.Server != nil { + if c.Requests = append(c.Requests, m); m.Cap("status") != "start" { running := make(chan bool) go m.AssertOne(m, true, func(m *Message) { - m.Log(m.Cap("status", "start"), c, "%d %v", m.Capi("nserver", 1), m.Meta["detail"]) + m.Log(m.Cap("status", "start"), nil, "%d server %v", m.Capi("nserver", 1), m.Meta["detail"]) - if m != c.Requests[0] { - c.Requests = append(c.Requests, m) - } - - if running <- true; c.Server.Start(m, m.Meta["detail"]...) { + if running <- true; c.Server != nil && c.Server.Start(m, m.Meta["detail"]...) { c.Close(m, m.Meta["detail"]...) } }) <-running } - return true } // }}} func (c *Context) Close(m *Message, arg ...string) bool { // {{{ - m.Log("close", c, "close %v", arg) + m.Log("close", c, "%v", arg) if m.Target == c { - switch { - case m.Index == 0: + if m.Index == 0 { for i := len(c.Requests) - 1; i >= 0; i-- { v := c.Requests[i] - v.Index = -1 - if v.Source != c && !v.Source.Close(v, arg...) { + if v.Index = -1; v.Source != c && !v.Source.Close(v, arg...) { v.Index = i return false } c.Requests = c.Requests[:i] } - case m.Index > 0: + } else if m.Index > 0 { for i := m.Index - 1; i < len(c.Requests)-1; i++ { c.Requests[i] = c.Requests[i+1] } @@ -193,22 +183,23 @@ func (c *Context) Close(m *Message, arg ...string) bool { // {{{ return true } - if len(c.Requests) > 0 { + if len(c.Requests) > 1 { return false } - m.Log(m.Cap("status", "close"), c, "%d server %v", m.root.Capi("nserver", -1)+1, arg) - if c.context != nil && len(c.contexts) == 0 { - m.Log("close", c, "%d context %v", m.root.Capi("ncontext", -1)+1, arg) - delete(c.context.contexts, c.Name) - } - - for _, v := range c.Sessions { - if v.Target != c { - v.Target.Close(v, arg...) + if m.Cap("status") == "start" { + m.Log(m.Cap("status", "close"), nil, "%d server %v", m.root.Capi("nserver", -1)+1, arg) + for _, v := range c.Sessions { + if v.Target != c { + v.Target.Close(v, arg...) + } } } + if m.Index == 0 && c.context != nil && len(c.contexts) == 0 { + m.Log("close", nil, "%d context %v", m.root.Capi("ncontext", -1)+1, arg) + delete(c.context.contexts, c.Name) + } return true } @@ -392,6 +383,7 @@ type Message struct { code int time time.Time + Recv chan bool Wait chan bool Meta map[string][]string Data map[string]interface{} @@ -538,7 +530,7 @@ func (m *Message) Assert(e interface{}, msg ...string) bool { // {{{ e = errors.New("error") } - m.Set("result", "error: ", fmt.Sprintln(e)) + m.Set("result", "error: ", fmt.Sprintln(e), "\n") panic(e) } @@ -832,7 +824,7 @@ func (m *Message) End(s bool) { // {{{ func (m *Message) Exec(key string, arg ...string) string { // {{{ - for _, c := range []*Context{m.Target, m.Target.Master, m.Source, m.Source.Master} { + for _, c := range []*Context{m.Target, m.Target.Master, m.Target.Owner, m.Source, m.Source.Master, m.Source.Owner} { for s := c; s != nil; s = s.context { m.Master = m.Source diff --git a/src/context/ssh/ssh.go b/src/context/ssh/ssh.go index 201100a2..8d1666a3 100644 --- a/src/context/ssh/ssh.go +++ b/src/context/ssh/ssh.go @@ -1,39 +1,153 @@ -package ssh - -import ( +package ssh // {{{ +// }}} +import ( // {{{ + "bufio" "context" + "fmt" + "net" + "net/url" + "strings" ) +// }}} + type SSH struct { + send map[string]*ctx.Message + *bufio.Reader + net.Conn *ctx.Context } -func (ssh *SSH) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { - c.Caches = map[string]*ctx.Cache{} +func (ssh *SSH) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ + c.Caches = map[string]*ctx.Cache{ + "nsend": &ctx.Cache{Name: "nsend", Value: "0", Help: "消息发送数量"}, + } c.Configs = map[string]*ctx.Config{} c.Commands = map[string]*ctx.Command{} s := new(SSH) s.Context = c + + s.send = make(map[string]*ctx.Message) return s } -func (ssh *SSH) Begin(m *ctx.Message, arg ...string) ctx.Server { +// }}} +func (ssh *SSH) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ + if ssh.Context == Index { + Pulse = m + } return ssh } -func (ssh *SSH) Start(m *ctx.Message, arg ...string) bool { +// }}} +func (ssh *SSH) Start(m *ctx.Message, arg ...string) bool { // {{{ + ssh.Owner = nil + ssh.Conn = m.Data["io"].(net.Conn) + ssh.Reader = bufio.NewReader(ssh.Conn) + m.Log("info", nil, "%d remote %v", 0, ssh.Conn.RemoteAddr()) + + target := m.Target + msg := m.Spawn(target) + + for { + line, e := ssh.Reader.ReadString('\n') + m.Assert(e) + + if line = strings.TrimSpace(line); len(line) == 0 { + if msg.Has("detail") { + msg.Log("info", nil, "remote: %v", msg.Meta["detail"]) + msg.Log("info", nil, "remote: %v", msg.Meta["option"]) + msg.Cmd(msg.Meta["detail"]...) + target = msg.Target + + fmt.Fprintf(ssh.Conn, "result: ") + for _, v := range msg.Meta["result"] { + fmt.Fprintf(ssh.Conn, "%s", url.QueryEscape(v)) + } + fmt.Fprintf(ssh.Conn, "\n") + + msg.Meta["append"] = append(msg.Meta["append"], "nsend") + msg.Add("append", "nsend", msg.Get("nsend")) + for _, k := range msg.Meta["append"] { + for _, v := range msg.Meta[k] { + fmt.Fprintf(ssh.Conn, "%s: %s\n", k, v) + } + } + fmt.Fprintf(ssh.Conn, "\n") + } else if msg.Has("result") { + msg.Log("info", nil, "remote: %v", msg.Meta["result"]) + msg.Log("info", nil, "remote: %v", msg.Meta["append"]) + send := ssh.send[msg.Get("nsend")] + send.Meta = msg.Meta + send.Recv <- true + } + msg = m.Spawn(target) + continue + } + + ls := strings.SplitN(line, ":", 2) + ls[0] = strings.TrimSpace(ls[0]) + ls[1], e = url.QueryUnescape(strings.TrimSpace(ls[1])) + m.Assert(e) + msg.Add("option", ls[0], ls[1]) + } return false } -func (ssh *SSH) Close(m *ctx.Message, arg ...string) bool { +// }}} +func (ssh *SSH) Close(m *ctx.Message, arg ...string) bool { // {{{ return false } +// }}} + +var Pulse *ctx.Message var Index = &ctx.Context{Name: "ssh", Help: "集群中心", - Caches: map[string]*ctx.Cache{}, - Configs: map[string]*ctx.Config{}, - Commands: map[string]*ctx.Command{}, + Caches: map[string]*ctx.Cache{ + "nhost": &ctx.Cache{Name: "nhost", Value: "0", Help: "主机数量"}, + }, + Configs: map[string]*ctx.Config{}, + Commands: map[string]*ctx.Command{ + "listen": &ctx.Command{Name: "listen address", Help: "监听连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { + tcp := m.Find("tcp", true) // {{{ + tcp.Cmd(m.Meta["detail"]...) + return "" + // }}} + }}, + "dial": &ctx.Command{Name: "dial address", Help: "建立连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { + tcp := m.Find("tcp", true) // {{{ + tcp.Cmd(m.Meta["detail"]...) + return "" + // }}} + }}, + "open": &ctx.Command{Name: "open", Help: "打开连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { + m.Start("host"+Pulse.Cap("nhost"), "主机连接") // {{{ + return "" + // }}} + }}, + "remote": &ctx.Command{Name: "remote detail...", Help: "远程执行", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { + ssh, ok := m.Target.Server.(*SSH) // {{{ + m.Assert(ok) + m.Capi("nsend", 1) + m.Recv = make(chan bool) + m.Add("option", "nsend", m.Cap("nsend")) + ssh.send[m.Cap("nsend")] = m + + for _, v := range arg { + fmt.Fprintf(ssh.Conn, "detail: %v\n", v) + } + for _, k := range m.Meta["option"] { + for _, v := range m.Meta[k] { + fmt.Fprintf(ssh.Conn, "%s: %s\n", k, v) + } + } + fmt.Fprintf(ssh.Conn, "\n") + <-m.Recv + return "" + // }}} + }}, + }, } func init() { From db10496c7f33774cdc905b8fb93a71bf5cd2b2f7 Mon Sep 17 00:00:00 2001 From: shaoying Date: Mon, 18 Dec 2017 00:15:08 +0800 Subject: [PATCH 3/4] mac mod readme --- README.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 417ced47..9aba2412 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,7 @@ context: 通过提供自由的模块,简洁的接口,动态的结构,让 * detail[] option[] result[] append[] * Context Master Owner -* Search() Action() Assert() Figure() - - +* Search() Choice() Assert() Figure() ## 结构设计 * 功能树 @@ -36,11 +34,9 @@ context: 通过提供自由的模块,简洁的接口,动态的结构,让 * 消息树 ## 分支管理 -* 0.1 ctx cli -* 0.2 mdb tcp -* 0.3 aaa ssh -* 0.4 web nfs -* 0.5 lex yac +* 0.1 ctx cli aaa ssh +* 0.2 nfs tcp mdb web +* 0.3 lex yac log gdb ## 终端管理 * 寻址 指令 事件 函数 资源 From 62d0f27fe42f08974b78e341ceae6cb326ed930f Mon Sep 17 00:00:00 2001 From: shaoying Date: Mon, 18 Dec 2017 00:16:38 +0800 Subject: [PATCH 4/4] =?UTF-8?q?mac=20add=20nfs=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=BA=86=E5=AD=98=E5=82=A8=E4=B8=AD=E5=BF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/context/mdb/mdb.go | 19 +++--- src/context/nfs/nfs.go | 135 +++++++++++++++++++++++++++++++++++++---- src/context/tcp/tcp.go | 18 ++++-- src/context/web/web.go | 7 ++- 4 files changed, 152 insertions(+), 27 deletions(-) diff --git a/src/context/mdb/mdb.go b/src/context/mdb/mdb.go index be0de87d..9cfd4c31 100644 --- a/src/context/mdb/mdb.go +++ b/src/context/mdb/mdb.go @@ -59,19 +59,18 @@ func (mdb *MDB) Start(m *ctx.Message, arg ...string) bool { // {{{ // }}} func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool { // {{{ - if mdb.Context == Index { - return false - } - switch mdb.Context { case m.Target: - case m.Source: - } + if mdb.Context == Index { + return false + } - if mdb.DB != nil { - m.Log("info", nil, "%d close %s %s", m.Capi("nsource", -1)+1, m.Cap("driver"), m.Cap("source")) - mdb.DB.Close() - mdb.DB = nil + if mdb.DB != nil { + m.Log("info", nil, "%d close %s %s", m.Capi("nsource", -1)+1, m.Cap("driver"), m.Cap("source")) + mdb.DB.Close() + mdb.DB = nil + } + case m.Source: } return true diff --git a/src/context/nfs/nfs.go b/src/context/nfs/nfs.go index 3473dab7..02cd72b6 100644 --- a/src/context/nfs/nfs.go +++ b/src/context/nfs/nfs.go @@ -1,38 +1,149 @@ -package nfs - -import ( +package nfs // {{{ +// }}} +import ( // {{{ "context" + + "fmt" + "io" + "os" + "strconv" ) +// }}} + type NFS struct { + file *os.File *ctx.Context } -func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { - c.Caches = map[string]*ctx.Cache{} +func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ + info, ok := m.Data["info"].(os.FileInfo) + m.Assert(ok) + + c.Caches = map[string]*ctx.Cache{ + "name": &ctx.Cache{Name: "name", Value: info.Name(), Help: "文件名"}, + "mode": &ctx.Cache{Name: "mode", Value: info.Mode().String(), Help: "文件名"}, + "time": &ctx.Cache{Name: "time", Value: info.ModTime().Format("15:03:04"), Help: "文件名"}, + "size": &ctx.Cache{Name: "size", Value: fmt.Sprintf("%d", info.Size()), Help: "文件名"}, + "pos": &ctx.Cache{Name: "pos", Value: "0", Help: "文件名"}, + } c.Configs = map[string]*ctx.Config{} s := new(NFS) s.Context = c return s + } -func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server { +// }}} +func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ + if nfs.Context == Index { + Pulse = m + } return nfs + } -func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { +// }}} +func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{ + m.Log("info", nil, "%d open %s", Pulse.Capi("nfile", 1), m.Cap("name")) + m.Cap("stream", m.Cap("name")) return false } -func (nfs *NFS) Exit(m *ctx.Message, arg ...string) bool { - return false +// }}} +func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool { // {{{ + switch nfs.Context { + case m.Target: + if nfs.Context == Index { + return false + } + + if nfs.file != nil { + m.Log("info", nil, "%d close %s", Pulse.Capi("nfile", -1)+1, m.Cap("name")) + nfs.file.Close() + return true + } + case m.Source: + } + + return true } +// }}} + +var Pulse *ctx.Message var Index = &ctx.Context{Name: "nfs", Help: "存储中心", - Caches: map[string]*ctx.Cache{}, - Configs: map[string]*ctx.Config{}, - Commands: map[string]*ctx.Command{}, + Caches: map[string]*ctx.Cache{ + "nfile": &ctx.Cache{Name: "nfile", Value: "0", Help: "已经打开的文件数量"}, + }, + Configs: map[string]*ctx.Config{ + "size": &ctx.Config{Name: "size", Value: "1024", Help: "读取文件的默认大小值"}, + }, + Commands: map[string]*ctx.Command{ + "open": &ctx.Command{Name: "open file", Help: "打开文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { + file, e := os.OpenFile(arg[0], os.O_RDWR|os.O_CREATE, os.ModePerm) // {{{ + m.Assert(e) + info, e := os.Stat(arg[0]) + m.Assert(e) + m.Put("option", "info", info).Start("file"+m.Cap("nfile"), "打开文件", arg...) + + nfs, ok := m.Target.Server.(*NFS) + m.Assert(ok) + + nfs.file = file + return "" + // }}} + }}, + "read": &ctx.Command{Name: "read [size [pos]]", Help: "读取文件, size: 读取大小, pos: 读取位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { + nfs, ok := m.Target.Server.(*NFS) // {{{ + m.Assert(ok) + + var e error + n := m.Confi("size") + if len(arg) > 0 { + n, e = strconv.Atoi(arg[0]) + m.Assert(e) + } + + buf := make([]byte, n) + if len(arg) > 1 { + m.Cap("pos", arg[1]) + } + + if n, e = nfs.file.ReadAt(buf, int64(m.Capi("pos"))); e != io.EOF { + m.Assert(e) + } + + if m.Capi("pos", n); m.Capi("pos") == m.Capi("size") { + m.Cap("pos", "0") + } + + return string(buf) + // }}} + }}, + "write": &ctx.Command{Name: "write string [pos]", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { + nfs, ok := m.Target.Server.(*NFS) // {{{ + if m.Assert(ok); len(arg) > 1 { + m.Cap("pos", arg[1]) + } + + if len(arg[0]) == 0 { + e := nfs.file.Truncate(0) + m.Assert(e) + m.Cap("size", "0") + m.Cap("pos", "0") + return "" + } + + n, e := nfs.file.WriteAt([]byte(arg[0]), int64(m.Capi("pos"))) + if m.Assert(e); m.Capi("pos", n) > m.Capi("size") { + m.Cap("size", m.Cap("pos")) + } + return m.Cap("pos") + // }}} + }}, + }, } func init() { diff --git a/src/context/tcp/tcp.go b/src/context/tcp/tcp.go index 809542f7..b8162a1d 100644 --- a/src/context/tcp/tcp.go +++ b/src/context/tcp/tcp.go @@ -56,6 +56,16 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{ m.Log("info", nil, "dial(%d) %v->%v", m.Capi("nclient", 1), tcp.LocalAddr(), tcp.RemoteAddr()) m.Cap("stream", fmt.Sprintf("%s->%s", tcp.LocalAddr(), tcp.RemoteAddr())) + msg := m.Spawn(m.Source).Put("option", "io", c) + msg.Cmd("open") + msg.Cap("stream", tcp.RemoteAddr().String()) + + if tcp.Sessions == nil { + tcp.Sessions = make(map[string]*ctx.Message) + } + tcp.Sessions["open"] = msg + msg.Name = "open" + // m.Reply(c.LocalAddr().String()).Put("option", "io", c).Cmd("open") return false case "accept": @@ -98,12 +108,12 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{ // }}} func (tcp *TCP) Close(m *ctx.Message, arg ...string) bool { // {{{ - if tcp.Context == Index { - return false - } - switch tcp.Context { case m.Target: + if tcp.Context == Index { + return false + } + if tcp.Listener != nil { m.Log("info", nil, "%d close %v", Pulse.Capi("nlisten", -1)+1, tcp.Listener.Addr()) tcp.Listener.Close() diff --git a/src/context/web/web.go b/src/context/web/web.go index 7ebd3f66..e7c6453c 100644 --- a/src/context/web/web.go +++ b/src/context/web/web.go @@ -194,7 +194,12 @@ func (web *WEB) Start(m *ctx.Message, arg ...string) bool { // {{{ // }}} func (web *WEB) Close(m *ctx.Message, arg ...string) bool { // {{{ - return false + switch web.Context { + case m.Target: + case m.Source: + } + + return true } // }}}