mirror of
https://shylinux.com/x/icebergs
synced 2025-04-26 01:24:05 +08:00
add log&gdb
This commit is contained in:
parent
a2dfaa3b19
commit
7a2f552db5
89
base.go
89
base.go
@ -2,11 +2,15 @@ package ice
|
||||
|
||||
import (
|
||||
"github.com/shylinux/toolkits"
|
||||
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Frame struct {
|
||||
code int
|
||||
}
|
||||
|
||||
func (f *Frame) Spawn(m *Message, c *Context, arg ...string) Server {
|
||||
@ -21,28 +25,15 @@ func (f *Frame) Begin(m *Message, arg ...string) Server {
|
||||
list[s] = sub
|
||||
}
|
||||
})
|
||||
m.target.wg = &sync.WaitGroup{}
|
||||
return f
|
||||
}
|
||||
func (f *Frame) Start(m *Message, arg ...string) bool {
|
||||
// 加载配置
|
||||
m.Travel(func(p *Context, s *Context) {
|
||||
if _, ok := s.Commands["_init"]; ok {
|
||||
m.Spawns(s).Runs("_init", "_init", arg...)
|
||||
}
|
||||
})
|
||||
|
||||
// 启动服务
|
||||
Index.begin.Cmd(arg)
|
||||
m.Cmd("_init").Cmd("init", arg)
|
||||
return true
|
||||
}
|
||||
func (f *Frame) Close(m *Message, arg ...string) bool {
|
||||
// 保存配置
|
||||
m.Travel(func(p *Context, s *Context) {
|
||||
if _, ok := s.Commands["_exit"]; ok {
|
||||
m.Spawns(s).Runs("_exit", "_exit", arg...)
|
||||
}
|
||||
})
|
||||
|
||||
m.target.wg.Wait()
|
||||
list := map[*Context]*Message{m.target: m}
|
||||
m.Travel(func(p *Context, s *Context) {
|
||||
if msg, ok := list[p]; ok && msg != nil {
|
||||
@ -55,29 +46,63 @@ func (f *Frame) Close(m *Message, arg ...string) bool {
|
||||
}
|
||||
|
||||
var Index = &Context{Name: "ice", Help: "冰山模块",
|
||||
Caches: map[string]*Cache{},
|
||||
Caches: map[string]*Cache{
|
||||
"status": {Value: "begin"},
|
||||
"stream": {Value: "shy"},
|
||||
},
|
||||
Configs: map[string]*Config{
|
||||
"table": {Name: "数据缓存", Value: map[string]interface{}{
|
||||
"space": " ",
|
||||
"col_sep": " ",
|
||||
"row_sep": "\n",
|
||||
"compact": "false",
|
||||
}},
|
||||
"cache": {Name: "数据缓存", Value: map[string]interface{}{
|
||||
"store": "var/data",
|
||||
"limit": "30",
|
||||
"least": "10",
|
||||
}},
|
||||
"help": {Value: map[string]interface{}{
|
||||
"index": []interface{}{
|
||||
"^_^ 欢迎使用冰山框架 ^_^",
|
||||
"^_^ Welcome to Icebergs world ^_^",
|
||||
"",
|
||||
"Meet: shylinuxc@gmail.com",
|
||||
"More: https://shylinux.com",
|
||||
"More: https://github.com/shylinux/icebergs",
|
||||
"",
|
||||
},
|
||||
}},
|
||||
},
|
||||
Commands: map[string]*Command{
|
||||
"_init": {Name: "_init", Help: "hello", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
|
||||
m.Travel(func(p *Context, s *Context) {
|
||||
if _, ok := s.Commands["_init"]; ok && p != nil {
|
||||
m.Spawns(s).Runs("_init", "_init", arg...)
|
||||
}
|
||||
})
|
||||
}},
|
||||
"init": {Name: "init", Help: "hello", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
|
||||
m.Start("log", arg...)
|
||||
m.Start("gdb", arg...)
|
||||
m.Start("ssh", arg...)
|
||||
m.Cmd(arg)
|
||||
}},
|
||||
"help": {Name: "help", Help: "帮助", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
|
||||
m.Echo(strings.Join(kit.Simple(m.Confv("help", "index")), "\n"))
|
||||
}},
|
||||
"exit": {Name: "exit", Help: "hello", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
|
||||
c.Close(m.Spawn(c), arg...)
|
||||
os.Exit(kit.Int(kit.Select("0", arg, 0)))
|
||||
}},
|
||||
"restart": {Name: "restart", Help: "hello", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
|
||||
switch kit.Select("0", arg, 0) {
|
||||
case "0":
|
||||
c.Close(m.Spawn(c), arg...)
|
||||
os.Exit(kit.Int(kit.Select("0", arg, 0)))
|
||||
}
|
||||
Code = kit.Int(kit.Select("0", arg, 0))
|
||||
m.root.Cmd("_exit")
|
||||
}},
|
||||
"_exit": {Name: "_init", Help: "hello", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
|
||||
m.root.Travel(func(p *Context, s *Context) {
|
||||
if _, ok := s.Commands["_exit"]; ok && p != nil {
|
||||
m.TryCatch(m.Spawns(s), true, func(msg *Message) {
|
||||
msg.Runs("_exit", "_exit", arg...)
|
||||
})
|
||||
}
|
||||
})
|
||||
}},
|
||||
},
|
||||
}
|
||||
@ -94,9 +119,10 @@ var Pulse = &Message{
|
||||
func init() {
|
||||
Index.root = Index
|
||||
Pulse.root = Pulse
|
||||
Index.server = &Frame{}
|
||||
}
|
||||
|
||||
var Code = 0
|
||||
|
||||
func Run(arg ...string) string {
|
||||
if len(arg) == 0 {
|
||||
arg = os.Args[1:]
|
||||
@ -105,8 +131,13 @@ func Run(arg ...string) string {
|
||||
arg = append(arg, os.Getenv("ice_serve"))
|
||||
}
|
||||
|
||||
if Index.Begin(Pulse.Spawns(), arg...).Start(Index.begin.Spawns(), arg...) {
|
||||
Index.Close(Index.start.Spawns(), arg...)
|
||||
frame := &Frame{}
|
||||
Index.server = frame
|
||||
|
||||
if frame.Begin(Pulse.Spawns(), arg...).Start(Pulse.Spawns(), arg...) {
|
||||
frame.Close(Pulse.Spawns(), arg...)
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
os.Exit(Code)
|
||||
return Pulse.Result()
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
"_init": {Name: "_init", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmd("ctx.config", "load", "var/conf/cli.json")
|
||||
|
||||
m.Conf("runtime", "host.GOARCH", runtime.GOARCH)
|
||||
m.Conf("runtime", "host.GOOS", runtime.GOOS)
|
||||
m.Conf("runtime", "host.pid", os.Getpid())
|
||||
@ -42,6 +44,9 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
|
||||
m.Conf("runtime", "node.name", m.Conf("runtime", "boot.pathname"))
|
||||
m.Log("info", "runtime %v", kit.Formats(m.Confv("runtime")))
|
||||
}},
|
||||
"_exit": {Name: "_exit", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmd("ctx.config", "save", "var/conf/cli.json", "cli.runtime")
|
||||
}},
|
||||
"runtime": {Name: "runtime", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
}},
|
||||
"system": {Name: "system", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
|
||||
|
@ -5,19 +5,40 @@ import (
|
||||
"github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/toolkits"
|
||||
"os"
|
||||
"sort"
|
||||
)
|
||||
|
||||
var Index = &ice.Context{Name: "ctx", Help: "元始模块",
|
||||
Caches: map[string]*ice.Cache{},
|
||||
Configs: map[string]*ice.Config{},
|
||||
Commands: map[string]*ice.Command{
|
||||
"context": {Name: "context", Help: "模块", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
ice.Pulse.Travel(func(p *ice.Context, s *ice.Context) {
|
||||
if p != nil {
|
||||
m.Push("ups", p.Name)
|
||||
} else {
|
||||
m.Push("ups", "shy")
|
||||
}
|
||||
m.Push("name", s.Name)
|
||||
m.Push("status", s.Cap("status"))
|
||||
m.Push("stream", s.Cap("stream"))
|
||||
m.Push("help", s.Help)
|
||||
})
|
||||
}},
|
||||
"command": {Name: "command", Help: "命令", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
ice.Pulse.Travel(func(p *ice.Context, s *ice.Context) {
|
||||
for k, v := range s.Commands {
|
||||
list := []string{}
|
||||
for k := range s.Commands {
|
||||
if k[0] == '/' || k[0] == '_' {
|
||||
continue
|
||||
}
|
||||
list = append(list, k)
|
||||
}
|
||||
sort.Strings(list)
|
||||
|
||||
for _, k := range list {
|
||||
v := s.Commands[k]
|
||||
if p != nil && p != ice.Index {
|
||||
m.Push("key", p.Name+"."+s.Name)
|
||||
} else {
|
||||
@ -39,10 +60,7 @@ var Index = &ice.Context{Name: "ctx", Help: "元始模块",
|
||||
m.Push("meta", kit.Format(i.Meta))
|
||||
m.Push("list", kit.Format(i.List))
|
||||
} else {
|
||||
switch arg[2] {
|
||||
case "run":
|
||||
m.Copy(m.Spawns(s).Runs(key, key, arg[3:]...))
|
||||
}
|
||||
m.Copy(m.Spawns(s).Runs(key, key, arg[3:]...))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
)
|
||||
|
||||
type Frame struct {
|
||||
signal chan os.Signal
|
||||
p chan os.Signal
|
||||
}
|
||||
|
||||
func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server {
|
||||
@ -22,35 +22,37 @@ func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server {
|
||||
f.WriteString(kit.Format(os.Getpid()))
|
||||
m.Log("info", "pid %d %s", os.Getpid(), p)
|
||||
}
|
||||
|
||||
f.signal = make(chan os.Signal, 10)
|
||||
m.Confm("signal", nil, func(sig string, action string) {
|
||||
m.Log("signal", "add %s: %s", sig, action)
|
||||
signal.Notify(f.signal, syscall.Signal(kit.Int(sig)))
|
||||
})
|
||||
|
||||
m.Gos(m, func(m *ice.Message) {
|
||||
if s, ok := <-f.signal; ok {
|
||||
m.Log("info", "signal %v", s)
|
||||
m.Cmd(m.Confv("signal", kit.Format(s)))
|
||||
}
|
||||
})
|
||||
m.Gos(m, func(m *ice.Message) {
|
||||
for {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
now := int(time.Now().Unix())
|
||||
m.Confm("timer", "hash", func(key string, value map[string]interface{}) {
|
||||
if kit.Int(value["next"]) <= now {
|
||||
m.Log("info", "timer %v %v", key, value["next"])
|
||||
m.Cmd(value["cmd"])
|
||||
value["next"] = now + int(kit.Duration(value["interval"]))/int(time.Second)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
return f
|
||||
}
|
||||
func (f *Frame) Start(m *ice.Message, arg ...string) bool {
|
||||
f.p = make(chan os.Signal, 10)
|
||||
m.Confm("signal", nil, func(sig string, action string) {
|
||||
m.Log("signal", "add %s: %s", sig, action)
|
||||
signal.Notify(f.p, syscall.Signal(kit.Int(sig)))
|
||||
})
|
||||
|
||||
m.Cap("stream", m.Conf("timer", "meta.tick"))
|
||||
tick := time.Tick(kit.Duration(m.Conf("timer", "meta.tick")))
|
||||
for {
|
||||
select {
|
||||
case sig, ok := <-f.p:
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
m.Log("info", "signal %v", sig)
|
||||
m.Cmd(m.Confv("signal", kit.Format(sig)))
|
||||
case now, _ := <-tick:
|
||||
// m.Log("info", "ticker %v", kit.Format(now))
|
||||
stamp := int(now.Unix())
|
||||
m.Confm("timer", "hash", func(key string, value map[string]interface{}) {
|
||||
if kit.Int(value["next"]) <= stamp {
|
||||
m.Log("info", "timer %v %v", key, value["next"])
|
||||
m.Cmd(value["cmd"])
|
||||
value["next"] = stamp + int(kit.Duration(value["interval"]))/int(time.Second)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (f *Frame) Close(m *ice.Message, arg ...string) bool {
|
||||
@ -62,18 +64,29 @@ var Index = &ice.Context{Name: "gdb", Help: "调试模块",
|
||||
Configs: map[string]*ice.Config{
|
||||
"logpid": &ice.Config{Name: "logpid", Value: "var/run/shy.pid", Help: ""},
|
||||
"signal": &ice.Config{Name: "signal", Value: map[string]interface{}{
|
||||
"2": []interface{}{"exit"}, "3": "QUIT", "15": "TERM",
|
||||
"2": []interface{}{"exit"},
|
||||
"3": []interface{}{"exit", "1"},
|
||||
"15": []interface{}{"exit", "1"},
|
||||
"30": []interface{}{"exit"},
|
||||
"31": []interface{}{"exit", "1"},
|
||||
"28": "WINCH",
|
||||
"30": "restart",
|
||||
"31": "upgrade",
|
||||
}, Help: "信号"},
|
||||
"timer": {Name: "定时器", Value: map[string]interface{}{
|
||||
"meta": map[string]interface{}{},
|
||||
"meta": map[string]interface{}{
|
||||
"tick": "100ms",
|
||||
},
|
||||
"hash": map[string]interface{}{},
|
||||
"list": map[string]interface{}{},
|
||||
}},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
"_init": {Name: "_init", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Echo("hello %s world", c.Name)
|
||||
}},
|
||||
"_exit": {Name: "_exit", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
f := m.Target().Server().(*Frame)
|
||||
close(f.p)
|
||||
}},
|
||||
"timer": {Name: "timer", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
switch arg[0] {
|
||||
case "start":
|
||||
|
@ -1,17 +1,93 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/toolkits"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
type Log struct {
|
||||
m *ice.Message
|
||||
level string
|
||||
str string
|
||||
}
|
||||
|
||||
type Frame struct {
|
||||
p chan *Log
|
||||
}
|
||||
|
||||
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)
|
||||
ice.Log = func(msg *ice.Message, level string, str string) {
|
||||
f.p <- &Log{m: msg, level: level, str: str}
|
||||
}
|
||||
return f
|
||||
}
|
||||
func (f *Frame) Start(m *ice.Message, arg ...string) bool {
|
||||
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("stream", path.Base(p))
|
||||
m.Log("info", "log %s %s", key, p)
|
||||
value["file"] = f
|
||||
}
|
||||
})
|
||||
|
||||
for {
|
||||
if l, ok := <-f.p; !ok {
|
||||
break
|
||||
} else {
|
||||
file := kit.Select("bench", m.Conf("show", l.level+".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")
|
||||
|
||||
for _, v := range ls {
|
||||
fmt.Fprintf(f, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (f *Frame) Close(m *ice.Message, arg ...string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
var Index = &ice.Context{Name: "log", Help: "日志模块",
|
||||
Caches: map[string]*ice.Cache{},
|
||||
Configs: map[string]*ice.Config{},
|
||||
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"},
|
||||
|
||||
"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"},
|
||||
|
||||
"cost": map[string]interface{}{"file": "bench", "prefix": "\033[33m", "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: "信号"},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
"hi": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
"_init": {Name: "_init", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Echo("hello %s world", c.Name)
|
||||
}},
|
||||
"_exit": {Name: "_exit", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
f := m.Target().Server().(*Frame)
|
||||
ice.Log = nil
|
||||
close(f.p)
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
func init() { ice.Index.Register(Index, nil) }
|
||||
func init() { ice.Index.Register(Index, &Frame{}) }
|
||||
|
@ -4,9 +4,13 @@ import (
|
||||
_ "github.com/shylinux/icebergs/base/aaa"
|
||||
_ "github.com/shylinux/icebergs/base/cli"
|
||||
_ "github.com/shylinux/icebergs/base/ctx"
|
||||
_ "github.com/shylinux/icebergs/base/web"
|
||||
|
||||
_ "github.com/shylinux/icebergs/base/gdb"
|
||||
_ "github.com/shylinux/icebergs/base/log"
|
||||
|
||||
_ "github.com/shylinux/icebergs/base/mdb"
|
||||
_ "github.com/shylinux/icebergs/base/nfs"
|
||||
_ "github.com/shylinux/icebergs/base/web"
|
||||
_ "github.com/shylinux/icebergs/base/ssh"
|
||||
_ "github.com/shylinux/icebergs/base/tcp"
|
||||
)
|
||||
|
@ -2,16 +2,73 @@ package ssh
|
||||
|
||||
import (
|
||||
"github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/toolkits"
|
||||
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
var Index = &ice.Context{Name: "ssh", Help: "远程模块",
|
||||
type Frame struct {
|
||||
in io.ReadCloser
|
||||
out io.WriteCloser
|
||||
}
|
||||
|
||||
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 {
|
||||
return f
|
||||
}
|
||||
func (f *Frame) Start(m *ice.Message, arg ...string) bool {
|
||||
f.in = os.Stdin
|
||||
f.out = os.Stdout
|
||||
m.Cap("stream", "stdio")
|
||||
|
||||
prompt := "%d[15:04:05]%s> "
|
||||
target := m.Target()
|
||||
count := 0
|
||||
|
||||
bio := bufio.NewScanner(f.in)
|
||||
fmt.Fprintf(f.out, m.Time(prompt, count, target.Name))
|
||||
for bio.Scan() {
|
||||
ls := kit.Split(bio.Text())
|
||||
m.Log("info", "input %v", ls)
|
||||
|
||||
msg := m.Spawn(target)
|
||||
if msg.Cmdy(ls); !msg.Hand {
|
||||
msg = msg.Cmdy("cli.system", ls)
|
||||
}
|
||||
res := msg.Result()
|
||||
if res == "" {
|
||||
msg.Table()
|
||||
res = msg.Result()
|
||||
}
|
||||
|
||||
fmt.Fprintf(f.out, res)
|
||||
fmt.Fprintf(f.out, m.Time(prompt, count, target.Name))
|
||||
count++
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (f *Frame) Close(m *ice.Message, arg ...string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
var Index = &ice.Context{Name: "ssh", Help: "终端模块",
|
||||
Caches: map[string]*ice.Cache{},
|
||||
Configs: map[string]*ice.Config{},
|
||||
Commands: map[string]*ice.Command{
|
||||
"hi": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
"_init": {Name: "_init", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Echo("hello %s world", c.Name)
|
||||
}},
|
||||
"_exit": {Name: "_exit", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
f := m.Target().Server().(*Frame)
|
||||
f.in.Close()
|
||||
m.Target().Done()
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
func init() { ice.Index.Register(Index, nil) }
|
||||
func init() { ice.Index.Register(Index, &Frame{}) }
|
||||
|
@ -2,14 +2,40 @@ package tcp
|
||||
|
||||
import (
|
||||
"github.com/shylinux/icebergs"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var Index = &ice.Context{Name: "tcp", Help: "网络模块",
|
||||
Caches: map[string]*ice.Cache{},
|
||||
Configs: map[string]*ice.Config{},
|
||||
Commands: map[string]*ice.Command{
|
||||
"hi": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Echo("hello %s world", c.Name)
|
||||
"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 {
|
||||
if len(arg) > 0 && !strings.Contains(v.Name, arg[0]) {
|
||||
continue
|
||||
}
|
||||
if ips, e := v.Addrs(); m.Assert(e) {
|
||||
for _, x := range ips {
|
||||
ip := strings.Split(x.String(), "/")
|
||||
if strings.Contains(ip[0], ":") || len(ip) == 0 {
|
||||
continue
|
||||
}
|
||||
if len(v.HardwareAddr.String()) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
m.Push("index", v.Index)
|
||||
m.Push("name", v.Name)
|
||||
m.Push("ip", ip[0])
|
||||
m.Push("mask", ip[1])
|
||||
m.Push("hard", v.HardwareAddr.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
m.Table()
|
||||
}
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
@ -269,6 +269,7 @@ func (web *WEB) Start(m *ice.Message, arg ...string) bool {
|
||||
})
|
||||
|
||||
port := kit.Select(m.Conf("spide", "self.port"), arg, 0)
|
||||
m.Cap("stream", port)
|
||||
web.m = m
|
||||
web.Server = &http.Server{Addr: port, Handler: web}
|
||||
m.Log("serve", "node %v", m.Conf("cli.runtime", "node"))
|
||||
@ -311,10 +312,13 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
"_init": {Name: "_init", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Echo("hello %s world", c.Name)
|
||||
}},
|
||||
"_exit": {Name: "_exit", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Target().Done()
|
||||
}},
|
||||
"serve": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Conf("cli.runtime", "node.type", "server")
|
||||
m.Conf("cli.runtime", "node.name", m.Conf("cli.runtime", "boot.hostname"))
|
||||
m.Run(arg...)
|
||||
m.Target().Start(m, arg...)
|
||||
}},
|
||||
"/space": &ice.Command{Name: "/space", Help: "", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
r := m.Optionv("request").(*http.Request)
|
||||
|
@ -18,7 +18,6 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块",
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
"_init": {Name: "_init", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmd("ctx.config", "load", "var/conf/cli.json")
|
||||
m.Cmd("ctx.config", "load", "var/conf/aaa.json")
|
||||
m.Cmd("ctx.config", "load", "var/conf/chat.json")
|
||||
}},
|
||||
@ -42,7 +41,6 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块",
|
||||
"_exit": {Name: "_init", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmd("ctx.config", "save", "var/conf/chat.json", "web.chat.group")
|
||||
m.Cmd("ctx.config", "save", "var/conf/aaa.json", "aaa.role", "aaa.user", "aaa.sess")
|
||||
m.Cmd("ctx.config", "save", "var/conf/cli.json", "cli.runtime")
|
||||
}},
|
||||
|
||||
"/login": {Name: "/login", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
export ice_app=${ice_app:="ice.app"}
|
||||
export ice_err=${ice_err:="boot.log"}
|
||||
export ice_conf=${ice_app:="var/conf"}
|
||||
export ice_serve=${ice_serve:="web.serve"}
|
||||
|
||||
prepare() {
|
||||
@ -38,13 +39,16 @@ build() {
|
||||
start() {
|
||||
[ -d usr/volcanos ] || git clone https://github.com/shylinux/volcanos usr/volcanos
|
||||
while true; do
|
||||
date && $ice_app $* 2>$ice_err && log "\n\nrestarting..." && sleep 1 || break
|
||||
date && $ice_app $* 2>$ice_err && log "\n\nrestarting..." || break
|
||||
done
|
||||
}
|
||||
log() { echo -e $*; }
|
||||
restart() {
|
||||
kill -2 `cat var/run/shy.pid`
|
||||
}
|
||||
shutdown() {
|
||||
kill -3 `cat var/run/shy.pid`
|
||||
}
|
||||
help() {
|
||||
echo "usage: $0 cmd arg"
|
||||
}
|
||||
|
11
demo/miss.md
11
demo/miss.md
@ -1,5 +1,16 @@
|
||||
# {{title "hello world"}}
|
||||
|
||||
init.register
|
||||
ice.Begin
|
||||
ice.Start
|
||||
ice.Close
|
||||
|
||||
{{chart "table" `
|
||||
ctx cli aaa web
|
||||
lex yac gdb log
|
||||
tcp nfs ssh mdb
|
||||
`}}
|
||||
|
||||
{{chart "chain" `
|
||||
context
|
||||
volcanos
|
||||
|
155
type.go
155
type.go
@ -13,6 +13,7 @@ import (
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -44,12 +45,13 @@ type Context struct {
|
||||
contexts map[string]*Context
|
||||
context *Context
|
||||
root *Context
|
||||
begin *Message
|
||||
start *Message
|
||||
|
||||
exit chan bool
|
||||
begin *Message
|
||||
start *Message
|
||||
server Server
|
||||
id int
|
||||
|
||||
wg *sync.WaitGroup
|
||||
id int
|
||||
}
|
||||
type Server interface {
|
||||
Spawn(m *Message, c *Context, arg ...string) Server
|
||||
@ -62,6 +64,12 @@ func (c *Context) ID() int {
|
||||
c.id++
|
||||
return c.id
|
||||
}
|
||||
func (c *Context) Cap(key string, arg ...interface{}) string {
|
||||
if len(arg) > 0 {
|
||||
c.Caches[key].Value = kit.Format(arg[0])
|
||||
}
|
||||
return c.Caches[key].Value
|
||||
}
|
||||
func (c *Context) Server() Server {
|
||||
return c.server
|
||||
}
|
||||
@ -77,18 +85,43 @@ func (c *Context) Register(s *Context, x Server) *Context {
|
||||
return s
|
||||
}
|
||||
|
||||
func (c *Context) Done() bool {
|
||||
if c.context != nil && c.context.wg != nil {
|
||||
c.context.wg.Done()
|
||||
} else {
|
||||
c.root.wg.Done()
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (c *Context) Begin(m *Message, arg ...string) *Context {
|
||||
c.begin = m
|
||||
c.Caches["status"] = &Cache{Name: "status", Value: ""}
|
||||
c.Caches["stream"] = &Cache{Name: "stream", Value: ""}
|
||||
|
||||
m.Log("begin", "%s", c.Name)
|
||||
if c.server != nil {
|
||||
c.server.Begin(m, arg...)
|
||||
if c.begin = m; c.server != nil {
|
||||
m.TryCatch(m, true, func(m *Message) {
|
||||
c.server.Begin(m, arg...)
|
||||
})
|
||||
}
|
||||
return c
|
||||
}
|
||||
func (c *Context) Start(m *Message, arg ...string) bool {
|
||||
c.start = m
|
||||
m.Log("start", "%s", c.Name)
|
||||
return c.server.Start(m, arg...)
|
||||
if c.context != nil && c.context.wg != nil {
|
||||
c.context.wg.Add(1)
|
||||
} else {
|
||||
c.root.wg.Add(1)
|
||||
}
|
||||
|
||||
m.Gos(m, func(m *Message) {
|
||||
m.Log("start", "%s", c.Name)
|
||||
|
||||
c.Cap("status", "start")
|
||||
c.server.Start(m, arg...)
|
||||
c.Cap("status", "close")
|
||||
c.Done()
|
||||
})
|
||||
return true
|
||||
}
|
||||
func (c *Context) Close(m *Message, arg ...string) bool {
|
||||
m.Log("close", "%s", c.Name)
|
||||
@ -347,6 +380,67 @@ func (m *Message) Table(cbs ...interface{}) *Message {
|
||||
cb(i, line, m.meta["append"])
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
//计算列宽
|
||||
space := kit.Select(m.Conf("table", "space"), m.Option("table.space"))
|
||||
depth, width := 0, map[string]int{}
|
||||
for _, k := range m.meta["append"] {
|
||||
if len(m.meta[k]) > depth {
|
||||
depth = len(m.meta[k])
|
||||
}
|
||||
width[k] = kit.Width(k, len(space))
|
||||
for _, v := range m.meta[k] {
|
||||
if kit.Width(v, len(space)) > width[k] {
|
||||
width[k] = kit.Width(v, len(space))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 回调函数
|
||||
rows := kit.Select(m.Conf("table", "row_sep"), m.Option("table.row_sep"))
|
||||
cols := kit.Select(m.Conf("table", "col_sep"), m.Option("table.col_sep"))
|
||||
compact := kit.Select(m.Conf("table", "compact"), m.Option("table.compact")) == "true"
|
||||
cb := func(maps map[string]string, lists []string, line int) bool {
|
||||
for i, v := range lists {
|
||||
if k := m.meta["append"][i]; compact {
|
||||
v = maps[k]
|
||||
}
|
||||
|
||||
if m.Echo(v); i < len(lists)-1 {
|
||||
m.Echo(cols)
|
||||
}
|
||||
}
|
||||
m.Echo(rows)
|
||||
return true
|
||||
}
|
||||
|
||||
// 输出表头
|
||||
row := map[string]string{}
|
||||
wor := []string{}
|
||||
for _, k := range m.meta["append"] {
|
||||
row[k], wor = k, append(wor, k+strings.Repeat(space, width[k]-kit.Width(k, len(space))))
|
||||
}
|
||||
if !cb(row, wor, -1) {
|
||||
return m
|
||||
}
|
||||
|
||||
// 输出数据
|
||||
for i := 0; i < depth; i++ {
|
||||
row := map[string]string{}
|
||||
wor := []string{}
|
||||
for _, k := range m.meta["append"] {
|
||||
data := ""
|
||||
if i < len(m.meta[k]) {
|
||||
data = m.meta[k][i]
|
||||
}
|
||||
|
||||
row[k], wor = data, append(wor, data+strings.Repeat(space, width[k]-kit.Width(data, len(space))))
|
||||
}
|
||||
if !cb(row, wor, i) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
@ -392,14 +486,19 @@ func (m *Message) Result(arg ...interface{}) string {
|
||||
return strings.Join(m.Resultv(), "")
|
||||
}
|
||||
|
||||
var Log func(*Message, string, string)
|
||||
|
||||
func (m *Message) Log(level string, str string, arg ...interface{}) *Message {
|
||||
if Log != nil {
|
||||
Log(m, level, fmt.Sprintf(str, arg...))
|
||||
}
|
||||
prefix, suffix := "", ""
|
||||
switch level {
|
||||
case "cmd":
|
||||
case "cmd", "start", "serve":
|
||||
prefix, suffix = "\033[32m", "\033[0m"
|
||||
case "cost":
|
||||
prefix, suffix = "\033[33m", "\033[0m"
|
||||
case "warn":
|
||||
case "warn", "close":
|
||||
prefix, suffix = "\033[31m", "\033[0m"
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "%s %d %s->%s %s%s %s%s\n",
|
||||
@ -446,8 +545,14 @@ func (m *Message) Travel(cb func(p *Context, s *Context)) *Message {
|
||||
list := []*Context{m.target}
|
||||
for i := 0; i < len(list); i++ {
|
||||
cb(list[i].context, list[i])
|
||||
for _, v := range list[i].contexts {
|
||||
list = append(list, v)
|
||||
|
||||
ls := []string{}
|
||||
for k := range list[i].contexts {
|
||||
ls = append(ls, k)
|
||||
}
|
||||
sort.Strings(ls)
|
||||
for _, k := range ls {
|
||||
list = append(list, list[i].contexts[k])
|
||||
}
|
||||
}
|
||||
return m
|
||||
@ -496,6 +601,14 @@ func (m *Message) Runs(key string, cmd string, arg ...string) *Message {
|
||||
}
|
||||
return m
|
||||
}
|
||||
func (m *Message) Start(key string, arg ...string) *Message {
|
||||
m.Travel(func(p *Context, s *Context) {
|
||||
if s.Name == key {
|
||||
s.Start(m.Spawns(s), arg...)
|
||||
}
|
||||
})
|
||||
return m
|
||||
}
|
||||
func (m *Message) Call(sync bool, cb func(*Message) *Message) *Message {
|
||||
if sync {
|
||||
wait := make(chan bool)
|
||||
@ -721,20 +834,23 @@ func (m *Message) Cmd(arg ...interface{}) *Message {
|
||||
return m
|
||||
}
|
||||
|
||||
msg := m
|
||||
m.Search(list[0], func(p *Context, s *Context, key string) {
|
||||
for c := s; c != nil; c = c.context {
|
||||
if cmd, ok := c.Commands[key]; ok {
|
||||
msg = m.Spawns(s).Log("cmd", "%s.%s %v", c.Name, key, list[1:])
|
||||
msg.meta["detail"] = list
|
||||
msg.TryCatch(msg, true, func(msg *Message) {
|
||||
m.TryCatch(m.Spawns(s), true, func(msg *Message) {
|
||||
|
||||
msg.Log("cmd", "%s.%s %v", c.Name, key, list[1:])
|
||||
msg.meta["detail"] = list
|
||||
cmd.Hand(msg, c, key, list[1:]...)
|
||||
msg.Hand = true
|
||||
m.Hand = true
|
||||
m = msg
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
return msg
|
||||
return m
|
||||
}
|
||||
func (m *Message) Confv(arg ...interface{}) (val interface{}) {
|
||||
m.Search(arg[0], func(p *Context, s *Context, key string) {
|
||||
@ -780,7 +896,8 @@ func (m *Message) Capv(arg ...interface{}) interface{} {
|
||||
for _, s := range []*Context{m.target} {
|
||||
for c := s; c != nil; c = c.context {
|
||||
if caps, ok := c.Caches[key]; ok {
|
||||
return kit.Value(caps.Value, arg[0])
|
||||
caps.Value = kit.Format(arg[0])
|
||||
return caps.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user