From ef1a5f03e4dc36a522553d7118b17e601da02213 Mon Sep 17 00:00:00 2001 From: shaoying Date: Sun, 29 Dec 2019 18:53:58 +0800 Subject: [PATCH] opt boot --- base/aaa/aaa.go | 37 ++++++----- base/cli/cli.go | 38 +++++++---- base/ctx/ctx.go | 2 +- base/gdb/gdb.go | 75 +++++++++++---------- base/lex/lex.go | 5 ++ base/log/log.go | 70 +++++++++++++------- base/mdb/mdb.go | 5 ++ base/nfs/nfs.go | 7 +- base/shy.go | 2 + base/ssh/ssh.go | 84 ++++++++++++++++-------- base/tcp/tcp.go | 5 ++ base/web/web.go | 164 ++++++++++++++++++++++++++-------------------- base/yac/yac.go | 5 ++ build.sh | 53 +++++++++------ conf.go | 32 +++++++-- core/chat/chat.go | 10 +-- core/code/code.go | 61 +++++++++++++++++ go.sum | 2 + misc/git/git.go | 16 ++++- misc/tmux/tmux.go | 2 + miss/miss.md | 59 +++++++++++++++++ type.go | 44 +++++++++---- 22 files changed, 549 insertions(+), 229 deletions(-) create mode 100644 miss/miss.md diff --git a/base/aaa/aaa.go b/base/aaa/aaa.go index 7cbb6026..49811a16 100644 --- a/base/aaa/aaa.go +++ b/base/aaa/aaa.go @@ -16,6 +16,7 @@ var Index = &ice.Context{Name: "aaa", Help: "认证模块", Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Cmd(ice.CTX_CONFIG, "load", "aaa.json") + // 权限索引 m.Conf(ice.AAA_ROLE, "black.tech.meta.short", "chain") m.Conf(ice.AAA_ROLE, "white.tech.meta.short", "chain") m.Conf(ice.AAA_ROLE, "black.void.meta.short", "chain") @@ -24,16 +25,19 @@ var Index = &ice.Context{Name: "aaa", Help: "认证模块", ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Cmd(ice.CTX_CONFIG, "save", "aaa.json", ice.AAA_ROLE, ice.AAA_USER, ice.AAA_SESS) }}, + ice.AAA_ROLE: {Name: "role", Help: "角色", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { switch arg[0] { case "check": + // 用户角色 m.Echo(kit.Select("void", "root", arg[1] == m.Conf(ice.CLI_RUNTIME, "boot.username"))) case "black", "white": + // 黑白名单 m.Rich(ice.AAA_ROLE, kit.Keys(arg[0], arg[1]), kit.Dict( - "chain", kit.Keys(arg[3:]), - "status", arg[2], + "status", arg[2], "chain", kit.Keys(arg[3:]), )) + m.Log(ice.LOG_ENABLE, "role: %s %s: %v", arg[1], arg[0], arg[3:]) case "right": if m.Option(ice.MSG_USERROLE) == ice.ROLE_ROOT { @@ -53,7 +57,7 @@ var Index = &ice.Context{Name: "aaa", Help: "认证模块", ok = value["status"] != "enable" }) } - if m.Warn(!ok, "no right %s", keys) { + if m.Warn(!ok, "black right %s", keys) { break } if m.Option(ice.MSG_USERROLE) == ice.ROLE_TECH { @@ -63,19 +67,16 @@ var Index = &ice.Context{Name: "aaa", Help: "认证模块", } ok = false - keys = strings.Split(kit.Keys(arg[2:]), ".") - m.Info("keys: %s", keys) for i := 0; i < len(keys); i++ { if ok { break } // 白名单 m.Richs(ice.AAA_ROLE, kit.Keys("white", arg[1]), kit.Keys(keys[:i+1]), func(key string, value map[string]interface{}) { - m.Info("value: %s", value) ok = value["status"] == "enable" }) } - if m.Warn(!ok, "no right %s", keys) { + if m.Warn(!ok, "no white right %s", keys) { break } // 普通用户 @@ -88,6 +89,7 @@ var Index = &ice.Context{Name: "aaa", Help: "认证模块", // 用户认证 user := m.Richs(ice.AAA_USER, nil, arg[1], nil) if user == nil { + // 创建用户 m.Rich(ice.AAA_USER, nil, kit.Dict( "username", arg[1], "password", arg[2], "usernode", m.Conf(ice.CLI_RUNTIME, "boot.hostname"), @@ -95,20 +97,25 @@ var Index = &ice.Context{Name: "aaa", Help: "认证模块", user = m.Richs(ice.AAA_USER, nil, arg[1], nil) m.Info("create user: %s %s", arg[1], kit.Format(user)) m.Event(ice.USER_CREATE, arg[1]) + } else if kit.Format(user["password"]) != arg[2] { + // 认证失败 m.Info("login fail user: %s", arg[1]) break } - // 用户授权 - sessid := kit.Format(user[ice.WEB_SESS]) - if sessid == "" { - role := m.Cmdx(ice.AAA_ROLE, "check", arg[1]) - sessid = m.Rich(ice.AAA_SESS, nil, kit.Dict( - "username", arg[1], "userrole", role, - )) - m.Info("user: %s role: %s sess: %s", arg[1], role, sessid) + if m.Options(ice.MSG_SESSID) && m.Cmdx(ice.AAA_SESS, "check", m.Option(ice.MSG_SESSID)) == arg[1] { + // 复用会话 + m.Echo(m.Option(ice.MSG_SESSID)) + break } + + // 创建会话 + role := m.Cmdx(ice.AAA_ROLE, "check", arg[1]) + sessid := m.Rich(ice.AAA_SESS, nil, kit.Dict( + "username", arg[1], "userrole", role, + )) + m.Info("user: %s role: %s sess: %s", arg[1], role, sessid) m.Echo(sessid) } }}, diff --git a/base/cli/cli.go b/base/cli/cli.go index 29629fb3..54107fe6 100644 --- a/base/cli/cli.go +++ b/base/cli/cli.go @@ -17,17 +17,24 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ ice.CLI_RUNTIME: {Name: "runtime", Help: "运行环境", Value: kit.Dict()}, + ice.CLI_SYSTEM: {Name: "system", Help: "系统命令", Value: kit.Data()}, }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Cmd(ice.CTX_CONFIG, "load", "cli.json") - m.Conf(ice.CLI_RUNTIME, "host.ctx_self", os.Getenv("ctx_self")) - m.Conf(ice.CLI_RUNTIME, "host.ctx_dev", os.Getenv("ctx_dev")) + // 启动配置 + m.Conf(ice.CLI_RUNTIME, "conf.ctx_self", os.Getenv("ctx_self")) + m.Conf(ice.CLI_RUNTIME, "conf.ctx_dev", os.Getenv("ctx_dev")) + m.Conf(ice.CLI_RUNTIME, "conf.ctx_shy", os.Getenv("ctx_shy")) + m.Conf(ice.CLI_RUNTIME, "conf.ctx_pid", os.Getenv("ctx_pid")) + + // 主机信息 m.Conf(ice.CLI_RUNTIME, "host.GOARCH", runtime.GOARCH) m.Conf(ice.CLI_RUNTIME, "host.GOOS", runtime.GOOS) m.Conf(ice.CLI_RUNTIME, "host.pid", os.Getpid()) + // 启动信息 if name, e := os.Hostname(); e == nil { m.Conf(ice.CLI_RUNTIME, "boot.hostname", kit.Select(name, os.Getenv("HOSTNAME"))) } @@ -37,18 +44,21 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块", if name, e := os.Getwd(); e == nil { m.Conf(ice.CLI_RUNTIME, "boot.pathname", path.Base(kit.Select(name, os.Getenv("PWD")))) } - m.Conf(ice.CLI_RUNTIME, "boot.time", m.Time()) + // 启动记录 count := m.Confi(ice.CLI_RUNTIME, "boot.count") + 1 m.Conf(ice.CLI_RUNTIME, "boot.count", count) - m.Conf(ice.CLI_RUNTIME, "node.type", kit.MIME_WORKER) + // 节点信息 + m.Conf(ice.CLI_RUNTIME, "node.time", m.Time()) + m.Conf(ice.CLI_RUNTIME, "node.type", ice.WEB_WORKER) m.Conf(ice.CLI_RUNTIME, "node.name", m.Conf(ice.CLI_RUNTIME, "boot.pathname")) m.Log("info", "runtime %v", kit.Formats(m.Confv(ice.CLI_RUNTIME))) }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "save", "cli.json", ice.CLI_RUNTIME) + m.Cmd(ice.CTX_CONFIG, "save", "cli.json", ice.CLI_RUNTIME, ice.CLI_SYSTEM) }}, + ice.CLI_RUNTIME: {Name: "runtime", Help: "运行环境", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }}, ice.CLI_SYSTEM: {Name: "system", Help: "系统命令", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { @@ -56,16 +66,21 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块", // 运行目录 cmd.Dir = m.Option("cmd_dir") - m.Info("dir: %s", cmd.Dir) + if len(cmd.Dir) > 0 { + m.Info("dir: %s", cmd.Dir) + } // 环境变量 env := kit.Simple(m.Optionv("cmd_env")) for i := 0; i < len(env)-1; i += 2 { cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", env[i], env[i+1])) } - m.Info("env: %s", cmd.Env) + if len(cmd.Env) > 0 { + m.Info("env: %s", cmd.Env) + } - if m.Option("cmd_type") == "daemon" { + switch m.Option("cmd_type") { + case "daemon": // 守护进程 m.Gos(m, func(m *ice.Message) { if e := cmd.Start(); e != nil { @@ -73,10 +88,10 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块", } else if e := cmd.Wait(); e != nil { m.Warn(e != nil, "%v wait: %s", arg, e) } else { - m.Info("%v exit", arg) + m.Cost("%v exit: %v", arg, cmd.ProcessState.ExitCode()) } }) - } else { + default: // 系统命令 out := bytes.NewBuffer(make([]byte, 0, 1024)) err := bytes.NewBuffer(make([]byte, 0, 1024)) @@ -85,9 +100,10 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块", if e := cmd.Run(); e != nil { m.Warn(e != nil, "%v run: %s", arg, kit.Select(e.Error(), err.String())) } else { - m.Echo(out.String()) + m.Cost("%v exit: %v", arg, cmd.ProcessState.ExitCode()) } m.Push("code", int(cmd.ProcessState.ExitCode())) + m.Echo(out.String()) } }}, }, diff --git a/base/ctx/ctx.go b/base/ctx/ctx.go index 6d415e96..09e7c112 100644 --- a/base/ctx/ctx.go +++ b/base/ctx/ctx.go @@ -79,7 +79,7 @@ var Index = &ice.Context{Name: "ctx", Help: "元始模块", }}, ice.CTX_CONFIG: {Name: "config", Help: "配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { - m.Travel(func(p *ice.Context, s *ice.Context, key string, conf *ice.Config) { + ice.Pulse.Travel(func(p *ice.Context, s *ice.Context, key string, conf *ice.Config) { m.Push("key", key) m.Push("name", conf.Name) m.Push("value", kit.Format(conf.Value)) diff --git a/base/gdb/gdb.go b/base/gdb/gdb.go index 396473d4..7d44458e 100644 --- a/base/gdb/gdb.go +++ b/base/gdb/gdb.go @@ -29,7 +29,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool { if !ok { return true } - m.Info("%s: %v", ice.GDB_SIGNAL, s) + m.Log(ice.LOG_SIGNAL, "%v: %v", s, m.Confv(ice.GDB_SIGNAL, kit.Keys(kit.MDB_HASH, s))) m.Cmd(m.Confv(ice.GDB_SIGNAL, kit.Keys(kit.MDB_HASH, s))) case t, ok := <-f.t: @@ -54,7 +54,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool { if !ok { return true } - m.Info("%s: %v", ice.GDB_EVENT, d) + m.Log(ice.LOG_EVENTS, "%s: %v", d[0], d[1:]) m.Grows(ice.GDB_EVENT, d[0], "", "", func(index int, value map[string]interface{}) { m.Cmd(value["cmd"], d[1:]).Cost("event %v", d) }) @@ -69,66 +69,73 @@ func (f *Frame) Close(m *ice.Message, arg ...string) bool { var Index = &ice.Context{Name: "gdb", Help: "事件模块", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ - ice.GDB_SIGNAL: {Name: "signal", Help: "信号器", Value: map[string]interface{}{ - kit.MDB_META: map[string]interface{}{ - "pid": "var/run/shy.pid", - }, - kit.MDB_HASH: map[string]interface{}{ - "2": []interface{}{"exit"}, - "3": []interface{}{"exit", "1"}, - "15": []interface{}{"exit"}, - "30": []interface{}{"exit"}, - "31": []interface{}{"exit", "1"}, - "28": "WINCH", - }, - kit.MDB_LIST: map[string]interface{}{}, - }}, + ice.GDB_SIGNAL: {Name: "signal", Help: "信号器", Value: kit.Dict( + kit.MDB_META, kit.Dict("pid", "var/run/ice.pid"), + kit.MDB_LIST, kit.List(), + kit.MDB_HASH, kit.Dict( + "2", []interface{}{"exit"}, + "3", []interface{}{"exit", "1"}, + "15", []interface{}{"exit"}, + "30", []interface{}{"exit"}, + "31", []interface{}{"exit", "1"}, + "28", "WINCH", + ), + )}, ice.GDB_TIMER: {Name: "timer", Help: "定时器", Value: kit.Data("tick", "100ms")}, ice.GDB_EVENT: {Name: "event", Help: "触发器", Value: kit.Data()}, }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if f, p, e := kit.Create(m.Conf(ice.GDB_SIGNAL, kit.Keys(kit.MDB_META, "pid"))); m.Assert(e) { - defer f.Close() - f.WriteString(kit.Format(os.Getpid())) - m.Log("info", "pid %d: %s", os.Getpid(), p) - } + // 进程标识 + m.Cmd("nfs.save", kit.Select(m.Conf(ice.GDB_SIGNAL, "meta.pid"), + m.Conf(ice.CLI_RUNTIME, "conf.ctx_pid")), m.Conf(ice.CLI_RUNTIME, "host.pid")) if f, ok := m.Target().Server().(*Frame); ok { + // 注册信号 f.s = make(chan os.Signal, ice.ICE_CHAN) - m.Confm(ice.GDB_SIGNAL, kit.MDB_HASH, func(sig string, action string) { - m.Log(ice.GDB_SIGNAL, "add %s: %s", sig, action) - signal.Notify(f.s, syscall.Signal(kit.Int(sig))) + m.Richs(ice.GDB_SIGNAL, nil, "*", func(key string, value string) { + m.Log(ice.LOG_LISTEN, "%s: %s", key, value) + signal.Notify(f.s, syscall.Signal(kit.Int(key))) }) - - f.t = time.Tick(kit.Duration(m.Cap(ice.CTX_STREAM, m.Conf(ice.GDB_TIMER, kit.Keys(kit.MDB_META, "tick"))))) + // 启动心跳 + f.t = time.Tick(kit.Duration(m.Cap(ice.CTX_STREAM, m.Conf(ice.GDB_TIMER, "meta.tick")))) + // 分发事件 f.d = make(chan []string, ice.ICE_CHAN) } }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if f, ok := m.Target().Server().(*Frame); ok { + // 停止心跳 close(f.s) + // 停止事件 close(f.d) } }}, ice.GDB_SIGNAL: {Name: "signal", Help: "信号器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Conf(ice.GDB_SIGNAL, kit.Keys(kit.MDB_META, arg[0]), arg[1:]) + switch arg[0] { + case "listen": + // 监听信号 + m.Rich(ice.GDB_SIGNAL, arg[0], arg[1:]) + } }}, ice.GDB_TIMER: {Name: "timer", Help: "定时器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { switch arg[0] { - case "start": - m.Rich(ice.GDB_TIMER, nil, map[string]interface{}{ - "next": time.Now().Add(kit.Duration(arg[1])).Unix(), - "interval": arg[1], "cmd": arg[2:], - }) + case "repeat": + // 周期命令 + m.Rich(ice.GDB_TIMER, nil, kit.Dict( + "next", time.Now().Add(kit.Duration(arg[1])).Unix(), + "interval", arg[1], "cmd", arg[2:], + )) } }}, ice.GDB_EVENT: {Name: "event", Help: "触发器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { switch arg[0] { case "listen": - m.Grow(ice.GDB_EVENT, arg[1], map[string]interface{}{"cmd": arg[2:]}) - + // 监听事件 + m.Grow(ice.GDB_EVENT, arg[1], kit.Dict("cmd", arg[2:])) + m.Log(ice.LOG_LISTEN, "%s: %v", arg[1], arg[2:]) case "action": + // 触发事件 if f, ok := m.Target().Server().(*Frame); ok { f.d <- arg[1:] } diff --git a/base/lex/lex.go b/base/lex/lex.go index 0f486400..8e973ddc 100644 --- a/base/lex/lex.go +++ b/base/lex/lex.go @@ -8,6 +8,11 @@ var Index = &ice.Context{Name: "lex", Help: "词法模块", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{}, Commands: map[string]*ice.Command{ + ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + }}, + ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + }}, + "hi": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Echo("hello %s world", c.Name) }}, diff --git a/base/log/log.go b/base/log/log.go index 30cc68a1..fa26c268 100644 --- a/base/log/log.go +++ b/base/log/log.go @@ -10,9 +10,9 @@ import ( ) type Log struct { - m *ice.Message - level string - str string + m *ice.Message + l string + s string } type Frame struct { @@ -23,9 +23,10 @@ func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server return &Frame{} } func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server { - f.p = make(chan *Log, 100) + // 日志管道 + f.p = make(chan *Log, 1024) ice.Log = func(msg *ice.Message, level string, str string) { - f.p <- &Log{m: msg, level: level, str: str} + f.p <- &Log{m: msg, l: level, s: str} } return f } @@ -34,13 +35,16 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool { if l, ok := <-f.p; !ok { break } else { - file := kit.Select("bench", m.Conf("show", l.level+".file")) + // 日志文件 + file := kit.Select("bench", m.Conf("show", l.l+".file")) f := m.Confv("file", file+".file").(*os.File) + // 日志内容 ls := []string{l.m.Format("prefix"), " "} - ls = append(ls, m.Conf("show", l.level+".prefix"), - l.level, " ", l.str, m.Conf("show", l.level+".suffix"), "\n") + ls = append(ls, m.Conf("show", l.l+".prefix"), + l.l, " ", l.s, m.Conf("show", l.l+".suffix"), "\n") + // 输出日志 for _, v := range ls { fmt.Fprintf(f, v) } @@ -55,36 +59,54 @@ func (f *Frame) Close(m *ice.Message, arg ...string) bool { var Index = &ice.Context{Name: "log", Help: "日志模块", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ - "file": &ice.Config{Name: "file", Value: map[string]interface{}{ - "bench": map[string]interface{}{"path": "var/log/bench.log"}, - }, Help: "信号"}, - "show": &ice.Config{Name: "file", Value: map[string]interface{}{ - "bench": map[string]interface{}{"file": "bench"}, + "file": &ice.Config{Name: "file", Help: "日志文件", Value: kit.Dict( + "watch", kit.Dict("path", "var/log/watch.log"), + "bench", kit.Dict("path", "var/log/bench.log"), + "error", kit.Dict("path", "var/log/error.log"), + "trace", kit.Dict("path", "var/log/trace.log"), + )}, + "show": &ice.Config{Name: "show", Help: "日志格式", Value: kit.Dict( + ice.LOG_ENABLE, kit.Dict("file", "watch"), + ice.LOG_IMPORT, kit.Dict("file", "watch"), + ice.LOG_CREATE, kit.Dict("file", "watch"), + ice.LOG_INSERT, kit.Dict("file", "watch"), + ice.LOG_EXPORT, kit.Dict("file", "watch"), - "cmd": map[string]interface{}{"file": "bench", "prefix": "\033[32m", "suffix": "\033[0m"}, - "start": map[string]interface{}{"file": "bench", "prefix": "\033[32m", "suffix": "\033[0m"}, - "serve": map[string]interface{}{"file": "bench", "prefix": "\033[32m", "suffix": "\033[0m"}, + ice.LOG_LISTEN, kit.Dict("file", "bench"), + ice.LOG_SIGNAL, kit.Dict("file", "bench"), + ice.LOG_TIMERS, kit.Dict("file", "bench"), + ice.LOG_EVENTS, kit.Dict("file", "bench"), - "cost": map[string]interface{}{"file": "bench", "prefix": "\033[33m", "suffix": "\033[0m"}, + ice.LOG_BEGIN, kit.Dict("file", "bench"), + ice.LOG_START, kit.Dict("file", "bench", "prefix", "\033[32m", "suffix", "\033[0m"), + ice.LOG_SERVE, kit.Dict("file", "bench", "prefix", "\033[32m", "suffix", "\033[0m"), + ice.LOG_CLOSE, kit.Dict("file", "bench", "prefix", "\033[31m", "suffix", "\033[0m"), - "warn": map[string]interface{}{"file": "bench", "prefix": "\033[31m", "suffix": "\033[0m"}, - "close": map[string]interface{}{"file": "bench", "prefix": "\033[31m", "suffix": "\033[0m"}, - }, Help: "信号"}, + ice.LOG_CMDS, kit.Dict("file", "bench", "prefix", "\033[32m", "suffix", "\033[0m"), + ice.LOG_COST, kit.Dict("file", "bench", "prefix", "\033[33m", "suffix", "\033[0m"), + ice.LOG_INFO, kit.Dict("file", "bench"), + ice.LOG_WARN, kit.Dict("file", "bench", "prefix", "\033[31m", "suffix", "\033[0m"), + ice.LOG_ERROR, kit.Dict("file", "error"), + ice.LOG_TRACE, kit.Dict("file", "trace"), + )}, }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Confm("file", nil, func(key string, value map[string]interface{}) { + // 日志文件 if f, p, e := kit.Create(kit.Format(value["path"])); m.Assert(e) { m.Cap(ice.CTX_STREAM, path.Base(p)) - m.Log("info", "log %s %s", key, p) + m.Log("create", "%s: %s", key, p) value["file"] = f } }) }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - f := m.Target().Server().(*Frame) - ice.Log = nil - close(f.p) + if f, ok := m.Target().Server().(*Frame); ok { + // 关闭日志 + ice.Log = nil + close(f.p) + } }}, }, } diff --git a/base/mdb/mdb.go b/base/mdb/mdb.go index 62db199f..5871e595 100644 --- a/base/mdb/mdb.go +++ b/base/mdb/mdb.go @@ -15,6 +15,11 @@ var Index = &ice.Context{Name: "mdb", Help: "数据模块", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{}, Commands: map[string]*ice.Command{ + ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + }}, + ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + }}, + "update": {Name: "update config table index key value", Help: "修改数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { meta := m.Confm(arg[0], arg[1]+".meta") index := kit.Int(arg[2]) - kit.Int(meta["offset"]) - 1 diff --git a/base/nfs/nfs.go b/base/nfs/nfs.go index 8934d358..97a528a7 100644 --- a/base/nfs/nfs.go +++ b/base/nfs/nfs.go @@ -131,6 +131,11 @@ var Index = &ice.Context{Name: "nfs", Help: "文件模块", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{}, Commands: map[string]*ice.Command{ + ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + }}, + ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + }}, + "dir": {Name: "dir", Help: "目录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { rg, _ := regexp.Compile(m.Option("dir_reg")) dir(m, arg[0], arg[1], 0, false, "both", rg, @@ -141,7 +146,7 @@ var Index = &ice.Context{Name: "nfs", Help: "文件模块", defer f.Close() for _, v := range arg[1:] { if n, e := f.WriteString(v); m.Assert(e) { - m.Log("info", "save %v %v", n, p) + m.Log("export", "%v: %v", n, p) m.Echo(p) } } diff --git a/base/shy.go b/base/shy.go index bf067483..f620ab45 100644 --- a/base/shy.go +++ b/base/shy.go @@ -7,7 +7,9 @@ import ( _ "github.com/shylinux/icebergs/base/web" _ "github.com/shylinux/icebergs/base/gdb" + _ "github.com/shylinux/icebergs/base/lex" _ "github.com/shylinux/icebergs/base/log" + _ "github.com/shylinux/icebergs/base/yac" _ "github.com/shylinux/icebergs/base/mdb" _ "github.com/shylinux/icebergs/base/nfs" diff --git a/base/ssh/ssh.go b/base/ssh/ssh.go index e52a0af9..eebac831 100644 --- a/base/ssh/ssh.go +++ b/base/ssh/ssh.go @@ -12,8 +12,24 @@ import ( ) type Frame struct { - in io.ReadCloser - out io.WriteCloser + in io.ReadCloser + out io.WriteCloser + target *ice.Context + count int +} + +func (f *Frame) prompt(m *ice.Message) *ice.Message { + prompt := "[15:04:05]%s> " + fmt.Fprintf(f.out, kit.Format("%d", f.count)) + fmt.Fprintf(f.out, m.Time(prompt, f.target.Name)) + return m +} +func (f *Frame) printf(m *ice.Message, res string) *ice.Message { + fmt.Fprint(f.out, res) + if !strings.HasSuffix(res, "\n") { + fmt.Fprint(f.out, "\n") + } + return m } func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server { @@ -23,37 +39,52 @@ func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server { return f } func (f *Frame) Start(m *ice.Message, arg ...string) bool { - f.in = os.Stdin - f.out = os.Stdout - m.Cap(ice.CTX_STREAM, "stdio") - - prompt := "%d[15:04:05]%s> " - target := m.Target() - count := 0 + switch kit.Select("stdio", arg, 0) { + default: + f.in = os.Stdin + f.out = os.Stdout + m.Cap(ice.CTX_STREAM, "stdio") + } + f.count = 0 + f.target = m.Target() bio := bufio.NewScanner(f.in) - fmt.Fprintf(f.out, m.Time(prompt, count, target.Name)) - for bio.Scan() { + for f.prompt(m); bio.Scan(); f.prompt(m) { ls := kit.Split(bio.Text()) - m.Log("info", "stdin input %v", ls) + m.Log(ice.LOG_IMPORT, "stdin: %v", ls) - msg := m.Spawns(target) + if len(ls) > 0 && strings.HasPrefix(ls[0], "~") { + // 切换模块 + target := ls[0][1:] + if ls = ls[1:]; len(target) == 0 { + target, ls = ls[0], ls[1:] + } + ice.Pulse.Search(target+".", func(p *ice.Context, s *ice.Context, key string) { + m.Info("choice: %s", s.Name) + f.target = s + }) + } + + if len(ls) == 0 { + continue + } + + // 执行命令 + msg := m.Spawns(f.target) if msg.Cmdy(ls); !msg.Hand { msg = msg.Set("result").Cmdy(ice.CLI_SYSTEM, ls) } + + // 生成结果 res := msg.Result() if res == "" { - msg.Table() - res = msg.Result() + res = msg.Table().Result() } - fmt.Fprint(f.out, res) - if !strings.HasSuffix(res, "\n") { - fmt.Fprint(f.out, "\n") - } - fmt.Fprintf(f.out, m.Time(prompt, count, target.Name)) - msg.Cost("stdin %v", ls) - count++ + // 输出结果 + msg.Cost("stdin:%v", ls) + f.printf(msg, res) + f.count++ } return true } @@ -66,12 +97,13 @@ var Index = &ice.Context{Name: "ssh", Help: "终端模块", Configs: map[string]*ice.Config{}, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Echo("hello %s world", c.Name) }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - f := m.Target().Server().(*Frame) - f.in.Close() - m.Done() + if f, ok := m.Target().Server().(*Frame); ok { + // 关闭终端 + f.in.Close() + m.Done() + } }}, }, } diff --git a/base/tcp/tcp.go b/base/tcp/tcp.go index 9e0caf1a..f17da547 100644 --- a/base/tcp/tcp.go +++ b/base/tcp/tcp.go @@ -11,6 +11,11 @@ var Index = &ice.Context{Name: "tcp", Help: "网络模块", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{}, Commands: map[string]*ice.Command{ + ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + }}, + ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + }}, + "ifconfig": {Name: "ifconfig [name]", Help: "网络配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if ifs, e := net.Interfaces(); m.Assert(e) { for _, v := range ifs { diff --git a/base/web/web.go b/base/web/web.go index 579309b6..b30c15a2 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -68,8 +68,8 @@ func (web *Frame) Login(msg *ice.Message, w http.ResponseWriter, r *http.Request } return msg.Option(ice.MSG_USERURL) != "" } -func (web *Frame) HandleWSS(m *ice.Message, safe bool, c *websocket.Conn) bool { - for { +func (web *Frame) HandleWSS(m *ice.Message, safe bool, c *websocket.Conn, name string) bool { + for running := true; running; { if t, b, e := c.ReadMessage(); m.Warn(e != nil, "space recv %d msg %v", t, e) { break } else { @@ -77,38 +77,40 @@ func (web *Frame) HandleWSS(m *ice.Message, safe bool, c *websocket.Conn) bool { case MSG_MAPS: // 接收报文 socket, msg := c, m.Spawn(b) - source := kit.Simple(msg.Optionv(ice.MSG_SOURCE)) + source := kit.Simple(msg.Optionv(ice.MSG_SOURCE), name) target := kit.Simple(msg.Optionv(ice.MSG_TARGET)) msg.Info("recv %v %v->%v %v", t, source, target, msg.Format("meta")) if len(target) == 0 { // 本地执行 if msg.Optionv(ice.MSG_HANDLE, "true"); !msg.Warn(!safe, "no right") { + m.Option("_dev", name) msg = msg.Cmd() } - kit.Revert(source) - source, target = []string{source[0]}, source[1:] + if source, target = []string{}, kit.Revert(source)[1:]; msg.Detail() == "exit" { + return true + } } else if s, ok := msg.Confv(ice.WEB_SPACE, kit.Keys("hash", target[0], "socket")).(*websocket.Conn); ok { // 转发报文 + socket, source, target = s, source, target[1:] msg.Info("space route") - socket, source, target = s, append(source, target[0]), target[1:] } else if call, ok := web.send[msg.Option(ice.MSG_TARGET)]; len(target) == 1 && ok { // 接收响应 - msg.Info("space done") delete(web.send, msg.Option(ice.MSG_TARGET)) + msg.Info("space done") call.Back(msg) break } else if msg.Warn(msg.Option("_handle") == "true", "space miss") { - // 丢弃报文 + // 回复失败 break } else { - // 失败报文 + // 下发失败 msg.Warn(true, "space error") - source, target = []string{source[len(source)-1]}, kit.Revert(source)[1:] + source, target = []string{}, kit.Revert(source)[1:] } // 发送报文 @@ -117,9 +119,6 @@ func (web *Frame) HandleWSS(m *ice.Message, safe bool, c *websocket.Conn) bool { socket.WriteMessage(t, []byte(msg.Format("meta"))) msg.Info("send %v %v->%v %v", t, source, target, msg.Format("meta")) msg.Log("cost", "%s: ", msg.Format("cost")) - if msg.Detail() == "exit" { - return true - } } } } @@ -335,7 +334,11 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", ice.WEB_SERVE: {Name: "serve", Help: "服务器", Value: kit.Data( "static", map[string]interface{}{"/": "usr/volcanos/", "/static/volcanos/": "usr/volcanos/", + "/publish/": "usr/publish/", }, + "volcanos", kit.Dict("path", "usr/volcanos", + "repos", "https://github.com/shylinux/volcanos", + "branch", "master"), "template", map[string]interface{}{"path": "usr/template", "list": []interface{}{ `{{define "raw"}}{{.Result}}{{end}}`, }}, @@ -360,18 +363,19 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Cmd(ice.CTX_CONFIG, "load", "web.json") + if m.Richs(ice.WEB_SPIDE, nil, "self", nil) == nil { - m.Cmd(ice.WEB_SPIDE, "add", "self", "http://:9020") - m.Cmd(ice.WEB_SPIDE, "add", "self", kit.Select("http://:9020", os.Getenv("ctx_dev"))) + m.Cmd(ice.WEB_SPIDE, "add", "self", kit.Select("http://:9020", m.Conf(ice.CLI_RUNTIME, "conf.ctx_self"))) } if m.Richs(ice.WEB_SPIDE, nil, "dev", nil) == nil { - m.Cmd(ice.WEB_SPIDE, "add", "dev", kit.Select("http://:9020", os.Getenv("ctx_dev"))) + m.Cmd(ice.WEB_SPIDE, "add", "dev", kit.Select("http://mac.local:9020", m.Conf(ice.CLI_RUNTIME, "conf.ctx_dev"))) } if m.Richs(ice.WEB_SPIDE, nil, "shy", nil) == nil { - m.Cmd(ice.WEB_SPIDE, "add", "shy", "https://shylinux.com") + m.Cmd(ice.WEB_SPIDE, "add", "shy", kit.Select("https://shylinux.com:443", m.Conf(ice.CLI_RUNTIME, "conf.ctx_shy"))) } }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Done() m.Done() m.Cmd(ice.CTX_CONFIG, "save", "web.json", ice.WEB_SPIDE, ice.WEB_FAVOR, ice.WEB_CACHE, ice.WEB_STORY, ice.WEB_SHARE) }}, @@ -418,6 +422,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", "url", arg[2], ), )) + m.Log(ice.LOG_CREATE, "%s: %v", arg[1], arg[2:]) } default: // spide shy [cache] [POST|GET] uri file|data|form|part|json arg... @@ -562,21 +567,15 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", } }}, ice.WEB_SERVE: {Name: "serve", Help: "服务器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + // 节点信息 m.Conf(ice.CLI_RUNTIME, "node.name", m.Conf(ice.CLI_RUNTIME, "boot.hostname")) - m.Conf(ice.CLI_RUNTIME, "node.type", kit.MIME_SERVER) + m.Conf(ice.CLI_RUNTIME, "node.type", ice.WEB_SERVER) - m.Rich(ice.WEB_SPACE, nil, kit.Dict( - "type", kit.MIME_MYSELF, - "name", m.Conf(ice.CLI_RUNTIME, "boot.hostname"), - "user", m.Conf(ice.CLI_RUNTIME, "boot.username"), - )) - if _, e := os.Stat("usr/volcanos"); e != nil { - m.Cmd("cli.system", "git", "clone", "https://github.com/shylinux/volcanos", "usr/volcanos") - } - if m.Conf(ice.CLI_RUNTIME, "boot.count") == "1" { - m.Event(ice.SYSTEM_INIT) - } + // 启动服务 m.Target().Start(m, kit.Select("self", arg, 0)) + m.Richs(ice.WEB_SPIDE, nil, "dev", func(key string, value map[string]interface{}) { + m.Cmd(ice.WEB_SPACE, "connect", "dev") + }) }}, ice.WEB_SPACE: {Name: "space", Help: "空间站", Meta: kit.Dict("exports", []string{"pod", "name"}), List: kit.List( kit.MDB_INPUT, "text", "name", "pod", @@ -591,13 +590,6 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", m.Sort("name") return } - if len(arg) == 1 { - // 节点详情 - m.Richs(ice.WEB_SPACE, nil, arg[0], func(key string, value map[string]interface{}) { - m.Push("detail", value) - }) - return - } web := m.Target().Server().(*Frame) switch arg[0] { @@ -606,9 +598,9 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", case "add": m.Cmdy(ice.WEB_SPIDE, "self", path.Join("/space/share/add", path.Join(arg[2:]...))) default: - m.Richs(ice.WEB_SPIDE, nil, "self", func(key string, value map[string]interface{}) { + m.Richs(ice.WEB_SPIDE, nil, m.Option("_dev"), func(key string, value map[string]interface{}) { + m.Log(ice.LOG_CREATE, "dev: %s share: %s", m.Option("_dev"), arg[1]) value["share"] = arg[1] - m.Info("what %v", kit.Formats(value)) }) } @@ -626,36 +618,51 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", case "connect": // 基本信息 + dev := kit.Select("dev", arg, 1) node := m.Conf(ice.CLI_RUNTIME, "node.type") - name := kit.Select(m.Conf(ice.CLI_RUNTIME, "boot.pathname"), m.Conf(ice.CLI_RUNTIME, "boot.hostname"), node == kit.MIME_SERVER) + name := m.Conf(ice.CLI_RUNTIME, "node.name") user := m.Conf(ice.CLI_RUNTIME, "boot.username") - m.Richs(ice.WEB_SPIDE, nil, kit.Select("self", arg, 1), func(key string, value map[string]interface{}) { - host := kit.Format(kit.Value(value, "client.hostname")) + m.Hold(1).Gos(m, func(m *ice.Message) { + m.Richs(ice.WEB_SPIDE, nil, dev, func(key string, value map[string]interface{}) { + proto := kit.Select("ws", "wss", kit.Format(kit.Value(value, "client.protocol")) == "https") + host := kit.Format(kit.Value(value, "client.hostname")) - for i := 0; i < m.Confi(ice.WEB_SPACE, "meta.redial.c"); i++ { - if u, e := url.Parse(kit.MergeURL("ws://"+host+"/space/", "node", node, "name", name, "user", user, "share", value["share"])); m.Assert(e) { - if s, e := net.Dial("tcp", host); !m.Warn(e != nil, "%s", e) { - if s, _, e := websocket.NewClient(s, u, nil, m.Confi(ice.WEB_SPACE, "meta.buffer.r"), m.Confi(ice.WEB_SPACE, "meta.buffer.w")); !m.Warn(e != nil, "%s", e) { - // 连接成功 - m.Info("conn %d success %s", i, u) - if i = 0; web.HandleWSS(m, true, s) { - break + for i := 0; i < m.Confi(ice.WEB_SPACE, "meta.redial.c"); i++ { + if u, e := url.Parse(kit.MergeURL(proto+"://"+host+"/space/", "node", node, "name", name, "user", user, "share", value["share"])); m.Assert(e) { + if s, e := net.Dial("tcp", host); !m.Warn(e != nil, "%s", e) { + if s, _, e := websocket.NewClient(s, u, nil, m.Confi(ice.WEB_SPACE, "meta.buffer.r"), m.Confi(ice.WEB_SPACE, "meta.buffer.w")); !m.Warn(e != nil, "%s", e) { + + // 连接成功 + m.Rich(ice.WEB_SPACE, nil, kit.Dict(kit.MDB_TYPE, ice.WEB_MASTER, kit.MDB_NAME, dev)) + m.Info("%d conn %s success %s", i, dev, u) + if i = 0; web.HandleWSS(m, true, s, dev) { + break + } } } - } - // 断线重连 - sleep := time.Duration(rand.Intn(m.Confi(ice.WEB_SPACE, "meta.redial.a"))*i+i*m.Confi(ice.WEB_SPACE, "meta.redial.b")) * time.Millisecond - m.Info("%d sleep: %s reconnect: %s", i, sleep, u) - time.Sleep(sleep) + // 断线重连 + sleep := time.Duration(rand.Intn(m.Confi(ice.WEB_SPACE, "meta.redial.a"))*i+i*m.Confi(ice.WEB_SPACE, "meta.redial.b")) * time.Millisecond + m.Info("%d sleep: %s reconnect: %s", i, sleep, u) + time.Sleep(sleep) + } } - } + }) + m.Done() }) default: - // 本地命令 - if arg[0] == "" || arg[0] == m.Conf(ice.CLI_RUNTIME, "node.name") { + if len(arg) == 1 { + // 节点详情 + m.Richs(ice.WEB_SPACE, nil, arg[0], func(key string, value map[string]interface{}) { + m.Push("detail", value) + }) + break + } + + if arg[0] == "" { + // 本地命令 m.Cmdy(arg[1:]) break } @@ -665,11 +672,11 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", if socket, ok := value["socket"].(*websocket.Conn); ok { // 构造路由 id := kit.Format(c.ID()) - m.Optionv(ice.MSG_SOURCE, []string{id, target[0]}) + m.Optionv(ice.MSG_SOURCE, []string{id}) m.Optionv(ice.MSG_TARGET, target[1:]) - m.Set(ice.MSG_DETAIL, arg[1:]...) m.Option("hot", m.Option("hot")) m.Option("top", m.Option("top")) + m.Set(ice.MSG_DETAIL, arg[1:]...) m.Info("send %s %s", id, m.Format("meta")) // 下发命令 @@ -846,7 +853,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", kit.MDB_TYPE, arg[1], kit.MDB_NAME, arg[2], kit.MDB_TEXT, arg[3], "extra", extra, )) - m.Info("create favor: %s index: %d name: %s", favor, index, arg[2]) + m.Log(ice.LOG_INSERT, "favor: %s index: %d name: %s", favor, index, arg[2]) m.Echo("%d", index) }}, ice.WEB_CACHE: {Name: "cache", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { @@ -861,6 +868,22 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", } switch arg[0] { + case "catch": + if f, e := os.Open(arg[2]); m.Assert(e) { + defer f.Close() + + h := kit.Hashs(f) + if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, ice.Meta("path")), h[:2], h)); m.Assert(e) { + defer o.Close() + f.Seek(0, os.SEEK_SET) + + if n, e := io.Copy(o, f); m.Assert(e) { + m.Log(ice.LOG_IMPORT, "%s: %s", kit.FmtSize(n), p) + arg = kit.Simple(arg[0], arg[1], path.Base(arg[2]), p, p, n) + } + } + } + fallthrough case "upload", "download": // 打开文件 if m.R != nil { @@ -901,7 +924,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", kit.MDB_FILE, kit.Select("", arg, 4), kit.MDB_SIZE, size, ) h := m.Rich(ice.WEB_CACHE, nil, data) - m.Info("cache: %s type: %s name: %s", h, arg[1], arg[2]) + m.Log(ice.LOG_CREATE, "cache: %s %s: %s", h, arg[1], arg[2]) // 保存数据 if arg[0] == "add" && len(arg) == 4 { @@ -960,9 +983,11 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", // head list data time text file switch arg[0] { + case "catch": + fallthrough case "add", "upload": // 保存数据 - if m.Richs(ice.WEB_CACHE, nil, arg[3], nil) == nil { + if m.Richs(ice.WEB_CACHE, nil, kit.Select("", arg, 3), nil) == nil { m.Cmdy(ice.WEB_CACHE, arg) arg = []string{arg[0], m.Append("type"), m.Append("name"), m.Append("data")} } @@ -978,7 +1003,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", list := m.Rich(ice.WEB_STORY, nil, kit.Dict( "count", count+1, "scene", arg[1], "story", arg[2], "data", arg[3], "prev", prev, )) - m.Info("%s: %s story: %s", arg[1], arg[2], list) + m.Log(ice.LOG_CREATE, "story: %s %s: %s", list, arg[1], arg[2]) m.Push("list", list) // 添加索引 @@ -1136,7 +1161,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", kit.MDB_TYPE, arg[1], kit.MDB_NAME, arg[2], kit.MDB_TEXT, arg[3], "share", h, )) - m.Info("share: %s %s", h, extra) + m.Log(ice.LOG_CREATE, "share: %s extra: %s", h, kit.Format(extra)) m.Echo(h) } }}, @@ -1188,7 +1213,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", return } - if s, e := websocket.Upgrade(m.W, m.R, nil, m.Confi(ice.WEB_SPACE, "meta.buffer"), m.Confi(ice.WEB_SPACE, "meta.buffer")); m.Assert(e) { + if s, e := websocket.Upgrade(m.W, m.R, nil, m.Confi(ice.WEB_SPACE, "meta.buffer.r"), m.Confi(ice.WEB_SPACE, "meta.buffer.w")); m.Assert(e) { // 共享空间 share := m.Option("share") if m.Richs(ice.WEB_SHARE, nil, share, nil) == nil { @@ -1200,17 +1225,16 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", kit.MDB_TYPE, m.Option("node"), kit.MDB_NAME, m.Option("name"), kit.MDB_USER, m.Option("user"), - "share", share, - "socket", s, + "share", share, "socket", s, )) - m.Info("space: %s", m.Option(kit.MDB_NAME)) + m.Log(ice.LOG_CREATE, "space: %s share: %s", m.Option(kit.MDB_NAME), share) m.Gos(m, func(m *ice.Message) { // 监听消息 m.Event(ice.SPACE_START, m.Option("node"), m.Option("name")) - m.Target().Server().(*Frame).HandleWSS(m, false, s) + m.Target().Server().(*Frame).HandleWSS(m, false, s, m.Option("name")) + m.Log(ice.LOG_CLOSE, "%s: %s", m.Option(kit.MDB_NAME), kit.Format(m.Confv(ice.WEB_SPACE, kit.Keys(kit.MDB_HASH, h)))) m.Event(ice.SPACE_CLOSE, m.Option("node"), m.Option("name")) - m.Log("close", "%s: %s", m.Option(kit.MDB_NAME), kit.Format(m.Confv(ice.WEB_SPACE, kit.Keys(kit.MDB_HASH, h)))) m.Confv(ice.WEB_SPACE, kit.Keys(kit.MDB_HASH, h), "") }) diff --git a/base/yac/yac.go b/base/yac/yac.go index 17b431ae..c4cd95c5 100644 --- a/base/yac/yac.go +++ b/base/yac/yac.go @@ -8,6 +8,11 @@ var Index = &ice.Context{Name: "yac", Help: "语法模块", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{}, Commands: map[string]*ice.Command{ + ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + }}, + ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + }}, + "hi": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Echo("hello %s world", c.Name) }}, diff --git a/build.sh b/build.sh index accfe048..0784d8d6 100755 --- a/build.sh +++ b/build.sh @@ -1,7 +1,5 @@ #! /bin/sh -ice_sh=${ice_sh:="ice.sh"} - prepare() { [ -f main.go ] || cat >> main.go <> ${ice_sh} <> Makefile <> ice.sh <boot.log && echo -e "\n\nrestarting..." || break done } restart() { - kill -2 \`cat var/run/shy.pid\` + [ -e \$ctx_pid ] && kill -2 \`cat \$ctx_pid\` || echo } shutdown() { - kill -3 \`cat var/run/shy.pid\` + [ -e \$ctx_pid ] && kill -3 \`cat \$ctx_pid\` || echo } -cmd=\$1 && shift -[ -z "\$cmd" ] && cmd=start +cmd=\$1 && [ -n "\$cmd" ] && shift || cmd=start \$cmd \$* END - chmod u+x ${ice_sh} - - [ -f Makefile ] || cat >> Makefile < 0 && arg[0] == "total" { diff --git a/misc/tmux/tmux.go b/misc/tmux/tmux.go index 8da685ef..61d541c2 100644 --- a/misc/tmux/tmux.go +++ b/misc/tmux/tmux.go @@ -53,6 +53,8 @@ var Index = &ice.Context{Name: "tmux", Help: "终端模块", Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Watch(ice.DREAM_START, "cli.tmux.auto") + return + m.Watch(ice.SERVE_START, "cli.tmux.auto") for _, p := range []string{"auto.sh", "auto.vim"} { if m.Richs(ice.WEB_STORY, "head", p, nil) == nil { m.Cmd(ice.WEB_STORY, "add", ice.TYPE_SHELL, p, m.Cmdx(ice.WEB_SPIDE, "shy", "cache", "GET", "/publish/"+p)) diff --git a/miss/miss.md b/miss/miss.md new file mode 100644 index 00000000..4d172f0c --- /dev/null +++ b/miss/miss.md @@ -0,0 +1,59 @@ +# icebergs + +icebergs是一个后端框架,通过模块化、集群化实现资源的无限的扩展与自由的组合。 + +一键创建项目 +``` +mkdir miss; cd miss && curl -s https://shylinux.com/publish/build.sh | sh +``` + +## 命令模块 base/cli + +cli模块用于与系统进行交互。 + +- 系统信息 ice.CLI_RUNTIME +- 系统命令 ice.CLI_SYSTEM + +## 终端模块 base/ssh + +ssh模块用于与终端交互。 + +## 日志模块 base/log + +log模块负责输出日志。 + +## 事件模块 base/gdb + +gdb模块会根据各种触发条件,择机执行各种命令。 + +- 信号器 ice.SIGNAL +- 定时器 ice.TIMER +- 触发器 ice.EVENT + +## 认证模块 base/aaa + +aaa模块用于各种权限管理与身份认证。 + +- 角色 ice.AAA_ROLE +- 用户 ice.AAA_USER +- 会话 ice.AAA_SESS + +## 网页模块 base/web + +web模块用于组织网络节点,与生成前端网页, + +- 网络爬虫 ice.WEB_SPIDE +- 网络服务 ice.WEB_SERVE +- 网络节点 ice.WEB_SPACE +- 网络任务 ice.WEB_DREAM + +- 网络收藏 ice.WEB_FAVOR +- 网络缓存 ice.WEB_CACHE +- 网络存储 ice.WEB_STORY +- 网络共享 ice.WEB_SHARE + +- 网络路由 ice.WEB_ROUTE +- 网络代理 ice.WEB_PROXY +- 网络分组 ice.WEB_GROUP +- 网络标签 ice.WEB_LABEL + diff --git a/type.go b/type.go index bbb61a42..fa2c4bb8 100644 --- a/type.go +++ b/type.go @@ -114,11 +114,7 @@ func (c *Context) Begin(m *Message, arg ...string) *Context { } func (c *Context) Start(m *Message, arg ...string) bool { c.start = m - if c.context != nil && c.context.wg != nil { - c.context.wg.Add(1) - } else { - c.root.wg.Add(1) - } + m.Hold(1) wait := make(chan bool) m.Gos(m, func(m *Message) { @@ -606,19 +602,27 @@ func (m *Message) Result(arg ...interface{}) string { } func (m *Message) Log(level string, str string, arg ...interface{}) *Message { - str = strings.TrimSpace(fmt.Sprintf(str, arg...)) - if Log != nil { + if str = strings.TrimSpace(fmt.Sprintf(str, arg...)); Log != nil { Log(m, level, str) } + prefix, suffix := "", "" switch level { - case LOG_CMDS, "start", "serve": + case LOG_ENABLE, LOG_IMPORT, LOG_CREATE, LOG_INSERT, LOG_EXPORT: + prefix, suffix = "\033[36;44m", "\033[0m" + + case LOG_LISTEN, LOG_SIGNAL, LOG_TIMERS, LOG_EVENTS: + prefix, suffix = "\033[33m", "\033[0m" + + case LOG_CMDS, LOG_START, LOG_SERVE: prefix, suffix = "\033[32m", "\033[0m" case LOG_COST: prefix, suffix = "\033[33m", "\033[0m" - case LOG_WARN, LOG_ERROR, "close": + case LOG_WARN, LOG_ERROR, LOG_CLOSE: prefix, suffix = "\033[31m", "\033[0m" } + + // 输出日志 fmt.Fprintf(os.Stderr, "%s %02d %9s %s%s %s%s\n", m.time.Format(ICE_TIME), m.code, fmt.Sprintf("%s->%s", m.source.Name, m.target.Name), prefix, level, str, suffix) @@ -691,11 +695,11 @@ func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) case io.EOF: case nil: default: - m.Log(LOG_ERROR, "catch: %s", e) - m.Log(LOG_BENCH, "chain: %s", msg.Format("chain")) - m.Log(LOG_ERROR, "catch: %s", e) - m.Log(LOG_BENCH, "stack: %s", msg.Format("stack")) - if m.Log(LOG_ERROR, "catch: %s", e); len(hand) > 1 { + m.Log(LOG_WARN, "catch: %s", e) + m.Log(LOG_INFO, "chain: %s", msg.Format("chain")) + m.Log(LOG_WARN, "catch: %s", e) + m.Log(LOG_INFO, "stack: %s", msg.Format("stack")) + if m.Log(LOG_WARN, "catch: %s", e); len(hand) > 1 { m.TryCatch(msg, safe, hand[1:]...) } else if !safe { m.Assert(e) @@ -716,6 +720,14 @@ func (m *Message) Run(arg ...string) *Message { m.target.server.Start(m, arg...) return m } +func (m *Message) Hold(n int) *Message { + if c := m.target; c.context != nil && c.context.wg != nil { + c.context.wg.Add(n) + } else { + c.root.wg.Add(n) + } + return m +} func (m *Message) Done() bool { defer func() { recover() }() if m.target.context != nil && m.target.context.wg != nil { @@ -860,6 +872,10 @@ func (m *Message) Richs(key string, chain interface{}, raw interface{}, cb inter case "*": // 全部遍历 switch cb := cb.(type) { + case func(string, string): + for k, v := range hash { + cb(k, kit.Format(v)) + } case func(string, map[string]interface{}): for k, v := range hash { res = v.(map[string]interface{})