1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-25 16:58:06 +08:00
This commit is contained in:
shaoying 2019-01-11 21:41:20 +08:00
parent 4651024817
commit a95dd9a346
11 changed files with 312 additions and 324 deletions

View File

@ -1,8 +0,0 @@
~web
config save web.json bench
~aaa
config save auth.json hash auth
~stdio
config save history.json history

View File

@ -1,15 +1,2 @@
~stdio
config load history.json
~aaa
# config load auth.json
~web
config load web.json
~aaa
role root componet index command source
user root shy shy
source etc/local.shy
source etc/spide.shy
~aaa
~ssh
remote listen :9090

View File

@ -58,7 +58,7 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server {
return cli
}
func (cli *CLI) Start(m *ctx.Message, arg ...string) bool {
m.Cap("stream", m.Spawn(m.Sess("yac", false).Target()).Call(func(cmd *ctx.Message) *ctx.Message {
m.Cap("stream", m.Sess("yac").Call(func(cmd *ctx.Message) *ctx.Message {
if !m.Caps("parse") {
switch cmd.Detail(0) {
case "if":
@ -81,9 +81,6 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool {
if v != nil {
m.Optionv("ps_target", v)
}
m.Set("append").Copy(cmd, "append")
m.Set("result").Copy(cmd, "result")
return nil
}, "scan", arg).Target().Name)
@ -136,6 +133,45 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
"timer_next": &ctx.Config{Name: "timer_next", Value: "", Help: "定时器"},
},
Commands: map[string]*ctx.Command{
"source": &ctx.Command{Name: "source [script|stdio|snippet]", Help: "解析脚本, script: 脚本文件, stdio: 命令终端, snippet: 代码片段", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
m.Cmdy("dir", "dir_deep", "dir_reg", ".*\\.(sh|shy|py)$")
return
}
// 解析脚本文件
if m.Cmds("nfs.path", arg[0]) {
switch path.Ext(arg[0]) {
case "":
case ".shy":
m.Option("scan_end", "false")
m.Start(fmt.Sprintf("shell%d", m.Capi("nshell", 1)), "shell", arg...)
m.Wait()
default:
m.Cmdy("system", m.Conf("cmd_script", strings.TrimPrefix(path.Ext(arg[0]), ".")), arg)
}
return
}
// 解析终端命令
if arg[0] == "stdio" {
m.Option("scan_end", "false")
m.Start("shy", "shell", "stdio", "engine")
m.Wait()
return
}
// 解析代码片段
m.Sess("yac").Call(func(msg *ctx.Message) *ctx.Message {
switch msg.Cmd().Detail(0) {
case "cmd":
m.Set("append").Copy(msg, "append")
m.Set("result").Copy(msg, "result")
}
return nil
}, "parse", "line", "void", strings.Join(arg, " "))
return
}},
"system": &ctx.Command{Name: "system word...", Help: []string{"调用系统命令, word: 命令",
"cmd_active(true/false): 是否交互", "cmd_timeout: 命令超时", "cmd_env: 环境变量", "cmd_dir: 工作目录"},
Form: map[string]int{"cmd_active": 1, "cmd_timeout": 1, "cmd_env": 2, "cmd_dir": 1, "cmd_error": 0, "cmd_parse": 1},
@ -163,9 +199,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
if v, ok := kit.Chain(conf, "path").(string); ok {
cmd.Path = m.Parse(v)
}
m.Log("info", "cmd.path %v", cmd.Path)
m.Log("info", "cmd.arg %v", cmd.Args)
m.Log("info", "cmd %v %v", cmd.Path, cmd.Args)
for k, v := range m.Confm("system_env") {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, m.Parse(v)))
@ -200,11 +234,10 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
} else {
wait := make(chan bool, 1)
go func() {
out := bytes.NewBuffer(make([]byte, 1024))
err := bytes.NewBuffer(make([]byte, 1024))
out := bytes.NewBuffer(make([]byte, 0, 1024))
err := bytes.NewBuffer(make([]byte, 0, 1024))
cmd.Stdout = out
cmd.Stderr = err
if e := cmd.Run(); e != nil {
m.Echo("error: ").Echo("%s\n", e).Echo(err.String())
} else {
@ -254,6 +287,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
}
return
}},
"alias": &ctx.Command{Name: "alias [short [long...]]|[delete short]|[import module [command [alias]]]",
Help: "查看、定义或删除命令别名, short: 命令别名, long: 命令原名, delete: 删除别名, import导入模块所有命令",
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
@ -683,80 +717,6 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
m.Set("result", m.Optionv("arguments"))
return
}},
"source": &ctx.Command{Name: "source [stdio [init_shy [exit_shy]]]|[filename [async]]|string", Help: "解析脚本, filename: 文件名, async: 异步执行",
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if _, ok := m.Source().Server.(*CLI); ok {
m.Copy(m.Spawn(c), "target")
}
if (len(arg) == 0 || arg[0] == "stdio") && m.Target().Name == "cli" {
// 启动终端
m.Cmd("yac.init")
m.Optionv("ps_target", m.Target())
if m.Start("shy", "shell", "stdio"); m.Cmds("nfs.path", m.Confx("init_shy", arg, 1)) {
// msg := m.Spawn().Add("option", "scan_end", "false").Cmd("source", m.Conf("init_shy"))
// m.Cap("ps_target", msg.Append("last_target"))
// m.Option("prompt", m.Conf("prompt"))
// m.Find("nfs.stdio").Cmd("prompt")
}
if m.Wait(); m.Cmds("nfs.path", m.Confx("exit_shy", arg, 2)) {
m.Spawn().Add("option", "scan_end", "false").Cmd("source", m.Conf("exit_shy"))
}
return
}
// 运行脚本
if m.Cmds("nfs.path", arg[0]) && strings.HasSuffix(arg[0], ".shy") {
m.Start(fmt.Sprintf("shell%d", m.Capi("nshell", 1)), "shell", arg...)
if len(arg) < 2 || arg[1] != "async" {
m.Wait()
} else {
m.Options("async", true)
}
return
}
// m.Confv("source_list", -1, map[string]interface{}{
// "source_time": m.Time(),
// "source_ctx": m.Option("current_ctx"),
// "source_cmd": strings.Join(arg, " "),
// })
//
if m.Options("current_ctx") {
args := []string{"context", m.Option("current_ctx")}
arg = append(args, arg...)
m.Option("current_ctx", "")
} else {
if !strings.HasPrefix(arg[0], "context") {
args := []string{"context", m.Source().Name}
arg = append(args, arg...)
}
}
m.Sess("yac").Call(func(msg *ctx.Message) *ctx.Message {
switch msg.Cmd().Detail(0) {
case "cmd":
m.Set("append").Copy(msg, "append")
m.Set("result").Copy(msg, "result")
}
return nil
}, "parse", "line", "void", strings.Join(arg, " "))
return
}},
"run": &ctx.Command{Name: "run", Help: "脚本参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
name := path.Join(m.Option("dir_root"), m.Option("download_dir"))
msg := m.Sess("nfs").Add("option", "dir_reg", ".*\\.(sh|shy|py)$").Add("option", "dir_root", "").Cmd("dir", name, "dir_deep")
m.Copy(msg, "append").Copy(msg, "result")
return
}
// name := path.Join(m.Option("dir_root"), m.Option("download_dir"), arg[0])
msg := m.Spawn(c).Cmd("cmd", arg[0], arg[1:])
m.Copy(msg, "append").Copy(msg, "result")
return
}},
"tmux": &ctx.Command{Name: "tmux buffer", Help: "终端管理, buffer: 查看复制", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
switch arg[0] {

View File

@ -105,6 +105,7 @@ func (c *Context) Begin(m *Message, arg ...string) *Context {
c.message = m
c.requests = append(c.requests, m)
m.source.sessions = append(m.source.sessions, m)
c.exit = make(chan bool, 3)
switch v := m.Gdb("context", "begin", c.Name).(type) {
case string:
@ -147,7 +148,6 @@ func (c *Context) Start(m *Message, arg ...string) bool {
return true
}
c.exit = make(chan bool, 2)
go m.TryCatch(m, true, func(m *Message) {
m.Log(m.Cap("status", "start"), "%d server %v %v", m.Capi("nserver", 1), m.Meta["detail"], m.Meta["option"])
@ -170,10 +170,10 @@ func (c *Context) Close(m *Message, arg ...string) bool {
return true
}
m.Log("close", "before %d:%d %v", len(c.requests), len(c.sessions), arg)
if m.target == c {
for i := len(c.requests) - 1; i >= 0; i-- {
if msg := c.requests[i]; msg.code == m.code {
m.Log("close", "request %d/%d", i, len(c.requests)-1)
if c.Server == nil || c.Server.Close(m, arg...) {
for j := i; j < len(c.requests)-1; j++ {
c.requests[j] = c.requests[j+1]
@ -184,7 +184,6 @@ func (c *Context) Close(m *Message, arg ...string) bool {
}
}
m.Log("close", "after %d:%d %v", len(c.requests), len(c.sessions), arg)
if len(c.requests) > 0 {
return false
}
@ -200,9 +199,7 @@ func (c *Context) Close(m *Message, arg ...string) bool {
if c.context != nil {
m.Log("close", "%d context %v", m.root.Capi("ncontext", -1), arg)
if c.Name != "stdio" {
delete(c.context.contexts, c.Name)
}
delete(c.context.contexts, c.Name)
c.exit <- true
}
return true
@ -1112,6 +1109,7 @@ func (m *Message) Sess(key string, arg ...interface{}) *Message {
if x, ok := msg.Sessions[key]; ok {
if spawn {
x = m.Spawn(x.target)
x.callback = func(sub *Message) *Message { return sub }
}
return x
}
@ -1292,6 +1290,9 @@ func (m *Message) Cmd(args ...interface{}) *Message {
arg = args
}
target := m.target
m.target = s
m.Hand = true
switch v := m.Gdb("command", key, arg).(type) {
case string:
@ -1299,6 +1300,9 @@ func (m *Message) Cmd(args ...interface{}) *Message {
case nil:
x.Hand(m, c, key, arg...)
}
if m.target == s {
m.target = target
}
})
}
return m.Hand
@ -3266,11 +3270,18 @@ func (ctx *CTX) Begin(m *Message, arg ...string) Server {
return ctx
}
func (ctx *CTX) Start(m *Message, arg ...string) bool {
gdb := m.Sess("gdb")
gdb.Target().Start(gdb)
m.Optionv("ps_target", Index)
m.Cmd("log.init")
m.Cmd("gdb.init")
if m.Cmd("yac.init", "lex"); len(arg) == 0 {
m.Cap("stream", "shy")
m.Cmd("cli.source", "init.shy").Cmd("cli.source", "stdio").Cmd("cli.source", "exit.shy")
return true
}
m.Cmd("cli.source", arg)
return false
return true
}
func (ctx *CTX) Close(m *Message, arg ...string) bool {
return true
@ -3283,8 +3294,9 @@ func Start(args ...string) bool {
args = append(args, os.Args[1:]...)
}
Index.Begin(Pulse, args...)
Index.Start(Pulse, args...)
Index.Close(Pulse, args...)
return false
if Index.Begin(Pulse, args...); Index.Start(Pulse, args...) {
return Index.Close(Pulse, args...)
}
return Index.message.Wait()
}

View File

@ -121,6 +121,10 @@ var Index = &ctx.Context{Name: "gdb", Help: "调试中心",
}},
},
Commands: map[string]*ctx.Command{
"init": &ctx.Command{Name: "init", Help: "等待调试", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Target().Start(m)
return
}},
"demo": &ctx.Command{Name: "wait arg...", Help: "等待调试", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Echo("hello world")
return

View File

@ -11,7 +11,8 @@ import (
)
type LOG struct {
file map[string]*os.File
queue chan map[string]interface{}
file map[string]*os.File
*ctx.Context
}
@ -33,29 +34,12 @@ func (log *LOG) Value(msg *ctx.Message, arg ...interface{}) map[string]interface
return nil
}
func (log *LOG) Log(msg *ctx.Message, action string, str string, arg ...interface{}) {
m := log.Message()
m.Capi("nlog", 1)
args := kit.Trans(arg...)
for _, v := range []string{action, "bench"} {
for i := len(args); i >= 0; i-- {
if value := log.Value(m, append([]string{v}, args[:i]...)); kit.Right(value) && kit.Right(value["file"]) {
name := path.Join(m.Conf("logdir"), kit.Format(value["file"]))
file, ok := log.file[name]
if !ok {
if f, e := os.Create(name); e == nil {
file, log.file[name] = f, f
kit.Log("error", "%s log file %s", "open", name)
} else {
kit.Log("error", "%s log file %s %s", "open", name, e)
continue
}
}
fmt.Fprintln(file, fmt.Sprintf("%d %s %s%s %s%s", m.Capi("nout", 1), msg.Format(value["meta"].([]interface{})...),
kit.Format(value["color_begin"]), action, fmt.Sprintf(str, arg...), kit.Format(value["color_end"])))
return
}
if log.queue != nil {
log.queue <- map[string]interface{}{
"action": action,
"str": str,
"arg": arg,
"msg": msg,
}
}
}
@ -69,19 +53,55 @@ func (log *LOG) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
return s
}
func (log *LOG) Begin(m *ctx.Message, arg ...string) ctx.Server {
return log
}
func (log *LOG) Start(m *ctx.Message, arg ...string) bool {
log.file = map[string]*os.File{}
os.Mkdir(m.Conf("logdir"), 0770)
os.MkdirAll(m.Conf("logdir"), 0770)
kit.Log("error", "make log dir %s", m.Conf("logdir"))
ioutil.WriteFile(m.Conf("logpid"), []byte(kit.Format(os.Getpid())), 0666)
kit.Log("error", "save log file %s", m.Conf("logpid"))
log.queue = make(chan map[string]interface{}, 1024)
for _, v := range []string{"error", "bench", "debug"} {
log.Log(m, v, "hello world\n")
log.Log(m, v, "hello world")
}
return log
}
func (log *LOG) Start(m *ctx.Message, arg ...string) bool {
m.Cap("stream", m.Conf("output", []string{"bench", "value", "file"}))
for {
select {
case l := <-log.queue:
m.Capi("nlog", 1)
msg := l["msg"].(*ctx.Message)
args := kit.Trans(l["arg"].([]interface{})...)
loop:
for _, v := range []string{kit.Format(l["action"]), "bench"} {
for i := len(args); i >= 0; i-- {
if value := log.Value(m, append([]string{v}, args[:i]...)); kit.Right(value) && kit.Right(value["file"]) {
name := path.Join(m.Conf("logdir"), kit.Format(value["file"]))
file, ok := log.file[name]
if !ok {
if f, e := os.Create(name); e == nil {
file, log.file[name] = f, f
kit.Log("error", "%s log file %s", "open", name)
} else {
kit.Log("error", "%s log file %s %s", "open", name, e)
continue
}
}
fmt.Fprintln(file, fmt.Sprintf("%d %s %s%s %s%s", m.Capi("nout", 1), msg.Format(value["meta"].([]interface{})...),
kit.Format(value["color_begin"]), kit.Format(l["action"]), fmt.Sprintf(kit.Format(l["str"]), l["arg"].([]interface{})...), kit.Format(value["color_end"])))
break loop
}
}
}
}
}
return false
}
func (log *LOG) Close(m *ctx.Message, arg ...string) bool {
@ -122,6 +142,10 @@ var Index = &ctx.Context{Name: "log", Help: "日志中心",
}, Help: "日志输出配置"},
},
Commands: map[string]*ctx.Command{
"init": &ctx.Command{Name: "init", Help: "启动日志", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Target().Start(m)
return
}},
"log": &ctx.Command{Name: "log level string...", Help: "输出日志, level: 日志类型, string: 日志内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if log, ok := m.Target().Server.(*LOG); m.Assert(ok) {
log.Log(m, arg[0], arg[1], arg[2:])

View File

@ -31,7 +31,6 @@ type NFS struct {
out *os.File
send chan *ctx.Message
recv chan *ctx.Message
hand map[int]*ctx.Message
*ctx.Context
@ -311,31 +310,29 @@ func (nfs *NFS) Term(msg *ctx.Message, action string, args ...interface{}) *NFS
nfs.Term(m, "print", m.Conf("prompt"))
case "print":
if m.Caps("termbox") {
for _, v := range kit.Format(args...) {
if x < right && y < bottom {
termbox.SetCell(x, y, v, fg, bg)
}
for _, v := range kit.Format(args...) {
if x < right && y < bottom {
termbox.SetCell(x, y, v, fg, bg)
}
if v > 255 {
x++
}
if x++; v == '\n' || (x >= right && m.Confs("term", "wrap")) {
x, y = left, y+1
}
if v > 255 {
x++
}
if x++; v == '\n' || (x >= right && m.Confs("term", "wrap")) {
x, y = left, y+1
}
if x < right && y < bottom {
m.Conf("term", "cursor_x", x)
m.Conf("term", "cursor_y", y)
termbox.SetCursor(x, y)
}
if x < right && y < bottom {
m.Conf("term", "cursor_x", x)
m.Conf("term", "cursor_y", y)
termbox.SetCursor(x, y)
}
if y >= bottom {
if !m.Options("scroll") {
nfs.Term(m, "scroll")
}
break
if y >= bottom {
if !m.Options("scroll") {
nfs.Term(m, "scroll")
}
break
}
}
case "color":
@ -460,6 +457,7 @@ func (nfs *NFS) Read(p []byte) (n int, err error) {
case termbox.KeyCtrlC:
nfs.Term(m, "exit")
n = copy(p, []byte("return\n"))
return
case termbox.KeyCtrlE:
@ -572,16 +570,14 @@ func (nfs *NFS) Read(p []byte) (n int, err error) {
func (nfs *NFS) printf(arg ...interface{}) *NFS {
m := nfs.Context.Message()
line := kit.Format(arg...)
if !strings.HasSuffix(line, "\n") {
line += "\n"
}
line := strings.TrimRight(kit.Format(arg...), "\n")
m.Log("debug", "noutput %s", m.Cap("noutput", m.Capi("noutput")+1))
m.Confv("output", -2, map[string]interface{}{"time": time.Now().Unix(), "line": line})
if m.Caps("termbox") {
nfs.Term(m, "clear").Term(m, "print", line).Term(m, "flush")
m.Conf("term", "prompt_y", m.Confi("term", "cursor_y"))
m.Conf("term", "prompt_y", m.Confi("term", "cursor_y")+1)
m.Conf("term", "cursor_y", m.Confi("term", "cursor_y")+1)
} else {
nfs.out.WriteString(line)
}
@ -589,8 +585,11 @@ func (nfs *NFS) printf(arg ...interface{}) *NFS {
}
func (nfs *NFS) prompt(arg ...interface{}) *NFS {
m := nfs.Context.Message()
target, _ := m.Optionv("ps_target").(*ctx.Context)
if target == nil {
target = nfs.Context
}
line := fmt.Sprintf("%d[%s]%s> ", m.Capi("ninput"), time.Now().Format("15:04:05"), target.Name)
m.Conf("prompt", line)
@ -598,7 +597,7 @@ func (nfs *NFS) prompt(arg ...interface{}) *NFS {
if m.Caps("termbox") {
m.Conf("term", "prompt_y", m.Conf("term", "cursor_y"))
nfs.Term(m, "clear").Term(m, "print", line).Term(m, "flush")
} else {
} else if nfs.out != nil {
nfs.out.WriteString(line)
}
return nfs
@ -642,6 +641,32 @@ func (nfs *NFS) shadow(args ...interface{}) *NFS {
return nfs
}
func (nfs *NFS) Send(meta string, arg ...interface{}) *NFS {
m := nfs.Context.Message()
n, e := fmt.Fprintf(nfs.io, "%s: %s\n", url.QueryEscape(meta), url.QueryEscape(kit.Format(arg[0])))
m.Assert(e)
m.Capi("nwrite", n)
return nfs
}
func (nfs *NFS) Recv(line string) (field string, value string) {
m := nfs.Context.Message()
m.Log("recv", "%d [%s]", len(line), line)
m.Capi("nread", len(line)+1)
word := strings.Split(line, ": ")
field, e := url.QueryUnescape(word[0])
m.Assert(e)
if len(word) == 1 {
return
}
value, e = url.QueryUnescape(word[1])
m.Assert(e)
return
}
func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
if len(arg) > 0 && (arg[0] == "scan" || arg[0] == "open" || arg[0] == "append") {
c.Caches = map[string]*ctx.Cache{
@ -703,11 +728,19 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
line, bio := "", bufio.NewScanner(nfs)
for nfs.prompt(); !m.Options("scan_end"); nfs.prompt() {
for bio.Scan() {
if line = line + bio.Text(); !strings.HasSuffix(line, "\\") {
if text := bio.Text(); text == "" {
continue
} else if !strings.HasSuffix(text, "\\") {
line += text
break
} else {
line += strings.TrimSuffix(text, "\\")
}
line = strings.TrimSuffix(line, "\\")
}
if line == "" {
line = "return"
}
m.Log("debug", "%s %d %d [%s]", "input", m.Capi("ninput", 1), len(line), line)
m.Confv("input", -2, map[string]interface{}{"time": time.Now().Unix(), "line": line})
@ -726,108 +759,73 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
}
line = ""
}
if !m.Options("scan_end") {
m.Backs(m.Spawn(m.Source()).Set("detail", "return"))
}
return true
return false
}
m.Cap("stream", m.Option("stream"))
m.Cap("stream", m.Option("ms_source"))
nfs.io = m.Optionv("io").(io.ReadWriter)
nfs.hand = map[int]*ctx.Message{}
nfs.send = make(chan *ctx.Message, 10)
nfs.recv = make(chan *ctx.Message, 10)
nfs.hand = map[int]*ctx.Message{}
go func() { //发送消息队列
for {
select {
case msg := <-nfs.send:
head, body := "detail", "option"
if msg.Hand {
head, body = "result", "append"
send_code := msg.Option("send_code")
msg.Append("send_code1", send_code)
m.Log("info", "%s recv: %v %v", msg.Option("recv_code"), msg.Meta[head], msg.Meta[body])
} else {
msg.Option("send_code", m.Capi("nsend", 1))
m.Log("info", "%d send: %v %v", m.Capi("nsend"), msg.Meta[head], msg.Meta[body])
nfs.hand[m.Capi("nsend")] = msg
code, meta, body := "0", "detail", "option"
if msg.Options("remote_code") { // 发送响应
code, meta, body = msg.Option("remote_code"), "result", "append"
} else { // 发送请求
code = kit.Format(m.Capi("nsend", 1))
nfs.hand[kit.Int(code)] = msg
}
for _, v := range msg.Meta[head] {
n, e := fmt.Fprintf(nfs.io, "%s: %s\n", head, url.QueryEscape(v))
m.Assert(e)
m.Capi("nwrite", n)
nfs.Send("code", code)
for _, v := range msg.Meta[meta] {
nfs.Send(meta, v)
}
for _, k := range msg.Meta[body] {
for _, v := range msg.Meta[k] {
n, e := fmt.Fprintf(nfs.io, "%s: %s\n", url.QueryEscape(k), url.QueryEscape(v))
m.Assert(e)
m.Capi("nwrite", n)
nfs.Send(k, v)
}
}
n, e := fmt.Fprintf(nfs.io, "\n")
m.Assert(e)
m.Capi("nwrite", n)
}
}
}()
go func() { //接收消息队列
var e error
var msg *ctx.Message
head, body := "", ""
//接收消息队列
msg, code, head, body := m, "0", "result", "append"
for bio := bufio.NewScanner(nfs.io); bio.Scan(); {
for bio := bufio.NewScanner(nfs.io); bio.Scan(); {
if msg == nil {
msg = m.Sess("target")
}
if msg.Meta == nil {
msg.Meta = map[string][]string{}
}
line := bio.Text()
m.Log("recv", "(%s) %s", head, line)
m.Capi("nread", len(line)+1)
if len(line) == 0 {
if head == "detail" {
m.Log("info", "%d recv: %v %v %v", m.Capi("nrecv", 1), msg.Meta[head], msg.Meta[body], msg.Meta)
msg.Option("recv_code", m.Cap("nrecv"))
nfs.recv <- msg
} else {
m.Log("info", "%d send: %v %v %v", msg.Appendi("send_code1"), msg.Meta[head], msg.Meta[body], msg.Meta)
h := nfs.hand[msg.Appendi("send_code1")]
h.Copy(msg, "result").Copy(msg, "append")
h.Remote <- true
}
msg, head, body = nil, "", "append"
continue
}
switch field, value := nfs.Recv(bio.Text()); field {
case "code":
msg, code = m.Sess("ms_target"), value
msg.Meta = map[string][]string{}
word := strings.Split(line, ": ")
word[0], e = url.QueryUnescape(word[0])
m.Assert(e)
word[1], e = url.QueryUnescape(word[1])
m.Assert(e)
switch word[0] {
case "detail":
head, body = "detail", "option"
msg.Add(word[0], word[1])
case "result":
head, body = "result", "append"
msg.Add(word[0], word[1])
default:
msg.Add(body, word[0], word[1])
case "detail":
head, body = "detail", "option"
msg.Add(field, value)
case "result":
head, body = "result", "append"
msg.Add(field, value)
case "":
if head == "detail" { // 接收请求
msg.Option("remote_code", code)
msg.Call(func(sub *ctx.Message) *ctx.Message {
nfs.send <- msg.Copy(sub, "append").Copy(sub, "result")
return nil
})
} else { // 接收响应
h := nfs.hand[kit.Int(code)]
h.Copy(msg, "result").Copy(msg, "append").Back(h)
}
msg, code, head, body = nil, "0", "result", "append"
default:
msg.Add(body, field, value)
}
}()
for {
select {
case msg := <-nfs.recv:
nfs.send <- msg.Cmd()
}
}
return true
@ -1237,7 +1235,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
if help := fmt.Sprintf("scan %s", arg[0]); arg[0] == "stdio" {
m.Put("option", "in", os.Stdin).Put("option", "out", os.Stdout).Start(arg[0], help, key, arg[0])
} else if p, f, e := open(m, arg[0]); m.Assert(e) {
m.Put("option", "in", f).Start(fmt.Sprintf("file%s", m.Capi("nfile")), help, key, p)
m.Put("option", "in", f).Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), help, key, p)
}
}
return
@ -1263,44 +1261,19 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
return
}},
"listen": &ctx.Command{Name: "listen args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
"remote": &ctx.Command{Name: "remote listen|dial args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { //{{{
m.Sess("tcp").Call(func(sub *ctx.Message) *ctx.Message {
sub.Sess("ms_target", m.Source())
sub.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "远程文件")
return sub.Sess("target", m.Source()).Call(func(sub1 *ctx.Message) *ctx.Message {
nfs, _ := sub.Target().Server.(*NFS)
sub1.Remote = make(chan bool, 1)
nfs.send <- sub1
<-sub1.Remote
return nil
})
}, m.Meta["detail"])
return sub
}, arg)
}
return
}},
"dial": &ctx.Command{Name: "dial args...", Help: "连接文件服务, args: 参考tcp模块, dial命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if _, ok := m.Target().Server.(*NFS); m.Assert(ok) {
m.Sess("tcp").Call(func(sub *ctx.Message) *ctx.Message {
sub.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "远程文件")
return sub.Sess("target", m.Source()).Call(func(sub1 *ctx.Message) *ctx.Message {
nfs, _ := sub.Target().Server.(*NFS)
sub1.Remote = make(chan bool, 1)
nfs.send <- sub1
<-sub1.Remote
return nil
})
}, m.Meta["detail"])
}
return
}},
"send": &ctx.Command{Name: "send [file] args...", Help: "连接文件服务, args: 参考tcp模块, dial命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.io != nil {
m.Remote = make(chan bool, 1)
nfs.send <- m
<-m.Remote
nfs.send <- m.Set("detail", arg)
}
return
}},

View File

@ -2,8 +2,8 @@ package ssh
import (
"contexts/ctx"
"fmt"
"strings"
"toolkit"
)
type SSH struct {
@ -37,32 +37,52 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
"domain": &ctx.Cache{Name: "domain", Value: "", Help: "主机域名"},
},
Configs: map[string]*ctx.Config{
"host": &ctx.Config{Name: "host", Value: map[string]interface{}{}, Help: "主机数量"},
"hostname": &ctx.Config{Name: "hostname", Value: "com", Help: "主机数量"},
"domain.json": &ctx.Config{Name: "domain.json", Value: "var/domain.json", Help: "主机数量"},
"domain.png": &ctx.Config{Name: "domain.png", Value: "var/domain.png", Help: "主机数量"},
},
Commands: map[string]*ctx.Command{
"listen": &ctx.Command{Name: "listen address [security [protocol]]", Help: "网络监听", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Sess("nfs").Call(func(sub *ctx.Message) *ctx.Message {
sub.Start(fmt.Sprintf("host%d", m.Capi("nhost", 1)), "远程主机")
// sub.Spawn().Cmd("pwd", "")
return sub
}, m.Meta["detail"])
if !m.Caps("domain") {
m.Cap("domain", m.Cap("hostname", m.Conf("hostname")))
"remote": &ctx.Command{Name: "remote listen|dial|send args...", Help: "网络监听", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
m.Cmdy("ctx.config", "host")
return
}
// m.Spawn(m.Target()).Cmd("save")
host := m.Confm("host", arg[0])
if host != nil {
arg = arg[1:]
}
switch arg[0] {
case "listen", "dial":
m.Call(func(sub *ctx.Message) *ctx.Message {
h, _ := kit.Hash("host", m.Option("ms_source"), "uniq")
m.Log("fuck", "what %v", sub.Format())
m.Confv("host", h, map[string]interface{}{
"module": sub.Cap("module"),
"type": arg[0],
})
return nil
}, "nfs.remote", arg)
case "exec":
m.Find(kit.Format(host["module"]), true).CallBack(true, func(sub *ctx.Message) *ctx.Message {
m.Copy(sub)
return nil
}, arg[1:])
}
return
}},
"dial": &ctx.Command{Name: "dial address [security [protocol]]", Help: "网络连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Sess("nfs").CallBack(true, func(sub *ctx.Message) *ctx.Message {
sub.Target().Start(sub)
return sub
}, m.Meta["detail"])
"demo": &ctx.Command{Name: "demo", Help: "远程执行", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Echo("demo")
return
}},
"send": &ctx.Command{Name: "send [domain str] cmd arg...", Help: "远程执行", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if ssh, ok := m.Target().Server.(*SSH); m.Assert(ok) {
origin, domain := "", ""
@ -138,6 +158,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
}
return
}},
"pwd": &ctx.Command{Name: "pwd [hostname]", Help: "主机域名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
m.Echo(m.Cap("domain"))

View File

@ -79,8 +79,10 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool {
m.Log("info", "%s dial %s", m.Cap("nclient"),
m.Cap("stream", fmt.Sprintf("%s->%s", tcp.LocalAddr(), tcp.RemoteAddr())))
m.Option("ms_source", tcp.Context.Name)
m.Put("option", "io", tcp).Back(m.Spawn(m.Source()))
return false
case "accept":
c, e := m.Optionv("io").(net.Conn)
m.Assert(e)
@ -89,9 +91,11 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool {
m.Log("info", "%s accept %s", m.Cap("nclient"),
m.Cap("stream", fmt.Sprintf("%s<-%s", tcp.LocalAddr(), tcp.RemoteAddr())))
m.Option("ms_source", tcp.Context.Name)
m.Put("option", "io", tcp).Back(m.Spawn(m.Source()))
return false
default:
case "listen":
if m.Caps("security") {
m.Sess("aaa", m.Sess("aaa").Cmd("login", "cert", m.Cap("certfile"), "key", m.Cap("keyfile"), "tcp"))
cert, e := tls.LoadX509KeyPair(m.Cap("certfile"), m.Cap("keyfile"))

View File

@ -224,7 +224,6 @@ func (yac *YAC) parse(m *ctx.Message, out *ctx.Message, page int, void int, line
} else if !m.Confs("exec", []string{yac.hand[hash], "disable"}) { //执行命令
msg := out.Spawn(m.Source()).Add("detail", yac.hand[hash], word)
if m.Back(msg); msg.Hand { //命令替换
m.Assert(!msg.Has("return"))
word = msg.Meta["result"]
}
}
@ -249,6 +248,7 @@ func (yac *YAC) Begin(m *ctx.Message, arg ...string) ctx.Server {
}
func (yac *YAC) Start(m *ctx.Message, arg ...string) (close bool) {
if len(arg) > 0 && arg[0] == "scan" {
m.Cap("stream", arg[1])
m.Sess("nfs").Call(func(input *ctx.Message) *ctx.Message {
_, word, _ := yac.parse(m, input, m.Optioni("page"), m.Optioni("void"), input.Detail(0)+"\n", 1)
input.Result(0, word)
@ -341,6 +341,9 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
yac.mat = make([]map[byte]*State, m.Confi("info", "nlang"))
yac.state = map[State]*State{}
if len(arg) > 0 {
yac.lex = m.Sess(arg[0])
}
m.Confm("seed", func(line int, seed map[string]interface{}) {
m.Spawn().Cmd("train", seed["page"], seed["hash"], seed["word"])
})
@ -386,14 +389,22 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
}
return
}},
"scan": &ctx.Command{Name: "scan filename", Help: "解析文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
"scan": &ctx.Command{Name: "scan filename modulename", Help: "解析文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
m.Optioni("page", yac.page["line"])
m.Optioni("void", yac.page["void"])
if len(arg) > 0 {
m.Start(fmt.Sprintf("parse%d", m.Capi("nparse", 1)), "parse", key, arg[0])
name := ""
if len(arg) > 1 {
name = arg[1]
} else {
m.Start(fmt.Sprintf("parse%d", m.Capi("nparse", 1)), "parse")
name = fmt.Sprintf("parse%d", m.Capi("nparse", 1))
}
if len(arg) > 0 {
m.Start(name, "parse", key, arg[0])
} else {
m.Start(name, "parse")
}
}
return

View File

@ -430,6 +430,21 @@ func Duration(arg ...string) time.Duration {
return d
}
func Action(cmd string, arg ...interface{}) string {
switch cmd {
case "time":
return Format(time.Now())
case "rand":
return Format(rand.Int())
case "uniq":
return Format(time.Now(), rand.Int())
default:
if len(arg) > 0 {
return Format(arg...)
}
}
return cmd
}
func Time(arg ...string) int {
if len(arg) == 0 {
return Int(time.Now())
@ -483,21 +498,6 @@ func FileName(name string, meta ...string) string {
return strings.Join(result, "")
}
func Action(cmd string, arg ...interface{}) string {
switch cmd {
case "time":
return Format(time.Now())
case "rand":
return Format(rand.Int())
case "uniq":
return Format(time.Now(), rand.Int())
default:
if len(arg) > 0 {
return Format(arg...)
}
}
return cmd
}
func Check(e error) bool {
if e != nil {
panic(e)