1
0
forked from x/ContextOS
Change-Id: I86d3d3a981795d3180ffd6f1a7468fcefbca8030
This commit is contained in:
shaoying 2019-03-17 11:40:23 +08:00
parent 1ae8f9d647
commit 0bc0e17674
17 changed files with 442 additions and 351 deletions

View File

@ -70,12 +70,14 @@ back_dotsfile:
cp ~/.zshrc $(DOTS) cp ~/.zshrc $(DOTS)
cp ~/.tmux.conf $(DOTS) cp ~/.tmux.conf $(DOTS)
cp ~/.vimrc $(DOTS) cp ~/.vimrc $(DOTS)
cp ~/.vim/syntax/go.vim $(DOTS)
cp ~/.vim/syntax/shy.vim $(DOTS) cp ~/.vim/syntax/shy.vim $(DOTS)
load_dotsfile:\ load_dotsfile:\
~/.zshrc\ ~/.zshrc\
~/.tmux.conf\ ~/.tmux.conf\
~/.vimrc\ ~/.vimrc\
~/.vim/syntax/go.vim\
~/.vim/syntax/shy.vim ~/.vim/syntax/shy.vim
~/.zshrc: $(DOTS)/.zshrc ~/.zshrc: $(DOTS)/.zshrc
@ -86,6 +88,8 @@ load_dotsfile:\
cp $< $@ cp $< $@
~/.vimrc: $(DOTS)/.vimrc ~/.vimrc: $(DOTS)/.vimrc
cp $< $@ cp $< $@
~/.vim/syntax/go.vim: $(DOTS)/go.vim
cp $< $@
~/.vim/syntax/shy.vim: $(DOTS)/shy.vim ~/.vim/syntax/shy.vim: $(DOTS)/shy.vim
cp $< $@ cp $< $@

View File

@ -1,5 +1,8 @@
~aaa ~mdb
user root shy shy note model favor spirit spirit relate relate
user root shaoying shaoying note model money expend expend amount amount
user root oLqNu5iJYXXLbHM9WuvM0W1obfHM what note model state active active elapse elapse
user root o978M0XIrcmco28CU1UbPgNxIL78 what note model event action action target target
note model proxy ctx text cmd text
note model share stuff stuff right right

View File

@ -42,14 +42,14 @@ bind i display-panes
bind x confirm-before -p "kill-pane #P? (y/n)" kill-pane bind x confirm-before -p "kill-pane #P? (y/n)" kill-pane
bind b break-pane bind b break-pane
bind u split-window # bind u split-window
bind v split-window -h # bind v split-window -h
bind C-u split-window -f # bind C-u split-window -f
bind C-v split-window -f -h # bind C-v split-window -f -h
# bind u split-window -c "#{pane_current_path}" bind u split-window -c "#{pane_current_path}"
# bind v split-window -h -c "#{pane_current_path}" bind v split-window -h -c "#{pane_current_path}"
# bind C-u split-window -f -c "#{pane_current_path}" bind C-u split-window -f -c "#{pane_current_path}"
# bind C-v split-window -f -h -c "#{pane_current_path}" bind C-v split-window -f -h -c "#{pane_current_path}"
bind h select-pane -L bind h select-pane -L
bind l select-pane -R bind l select-pane -R

View File

@ -78,8 +78,9 @@ let g:syntastic_quiet_messages = { "regex": [
\ ] } \ ] }
Plug 'Valloric/YouCompleteMe' Plug 'Valloric/YouCompleteMe'
let g:syntastic_enable_signs = 1 let g:ycm_confirm_extra_conf=1
let g:ycm_confirm_extra_conf=0 let g:syntastic_enable_signs=1
let g:ycm_python_binary_path='/usr/bin/python'
nnoremap gd :YcmCompleter GoToDeclaration<CR> nnoremap gd :YcmCompleter GoToDeclaration<CR>
nnoremap gD :YcmCompleter GoToReferences<CR> nnoremap gD :YcmCompleter GoToReferences<CR>
@ -136,6 +137,7 @@ nnoremap j gj
nnoremap k gk nnoremap k gk
nnoremap <C-M> :make<CR> nnoremap <C-M> :make<CR>
inoremap <C-M> <ESC>:make<CR>i
nnoremap df :FZF<CR> nnoremap df :FZF<CR>
inoremap df _ inoremap df _
@ -161,6 +163,8 @@ function! Config(type)
set filetype=xml set filetype=xml
elseif a:type == "css" elseif a:type == "css"
set filetype=css set filetype=css
elseif a:type == "txt"
set noexpandtab
endif endif
endfunction endfunction
@ -173,6 +177,7 @@ autocmd BufNewFile,BufReadPost *.json call Config("json")
autocmd BufNewFile,BufReadPost *.wxml call Config("xml") autocmd BufNewFile,BufReadPost *.wxml call Config("xml")
autocmd BufNewFile,BufReadPost *.wxss call Config("css") autocmd BufNewFile,BufReadPost *.wxss call Config("css")
autocmd BufNewFile,BufReadPost *.txt call Config("txt")
command! RR wa | source ~/.vimrc |e command! RR wa | source ~/.vimrc |e
command! SS mksession! etc/session.vim command! SS mksession! etc/session.vim

View File

@ -7,6 +7,8 @@ syntax match shyCache "\(^\|\t\| \|$(\)cache\>"
syntax match shyString "'[^']*'" syntax match shyString "'[^']*'"
syntax match shyString "\"[^\"]*\"" syntax match shyString "\"[^\"]*\""
syntax match shyNumber "-\=\<\d\+\>#\=" syntax match shyNumber "-\=\<\d\+\>#\="
syntax match shyNumber "false"
syntax match shyNumber "true"
syntax match shVariable "\$[_a-zA-Z0-9]\+\>" syntax match shVariable "\$[_a-zA-Z0-9]\+\>"
syntax match shVariable "@[_a-zA-Z0-9]\+\>" syntax match shVariable "@[_a-zA-Z0-9]\+\>"

View File

@ -3,14 +3,6 @@
# ~mdb # ~mdb
# config load note.json note # config load note.json note
# #
~mdb
note model favor spirit spirit relate relate
note model money expend expend amount amount
note model state active active elapse elapse
note model event action action target target
note model proxy ctx text cmd text
note model share stuff stuff right right
source common.shy source common.shy
~ssh ~ssh
remote auto remote auto

View File

@ -536,6 +536,19 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
return true return true
}, },
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) > 0 && arg[0] == "current" {
switch len(arg) {
case 1:
m.Cmdy("aaa.auth", m.Option("sessid"), "data", "current")
case 2:
m.Cmdy("aaa.auth", m.Option("sessid"), "data", "current."+arg[1])
default:
m.Cmd("aaa.auth", m.Option("sessid"), "data", "current."+arg[1], arg[2])
m.Cmdy("aaa.auth", m.Option("sessid"), "data", "current."+arg[1])
}
return
}
switch len(arg) { switch len(arg) {
case 0: // 查看会话 case 0: // 查看会话
m.Cmdy("aaa.auth", "ship", "session") m.Cmdy("aaa.auth", "ship", "session")

View File

@ -191,6 +191,11 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
return return
} }
text := strings.Join(arg, " ")
if !strings.HasPrefix(text, "sess") {
text = m.Current(text)
}
// 解析代码片段 // 解析代码片段
m.Sess("yac").Call(func(msg *ctx.Message) *ctx.Message { m.Sess("yac").Call(func(msg *ctx.Message) *ctx.Message {
switch msg.Cmd().Detail(0) { switch msg.Cmd().Detail(0) {
@ -199,7 +204,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
m.Set("result").Copy(msg, "result") m.Set("result").Copy(msg, "result")
} }
return nil return nil
}, "parse", "line", "void", strings.Join(arg, " ")) }, "parse", "line", "void", text)
return return
}}, }},
"system": &ctx.Command{Name: "system word...", Help: []string{"调用系统命令, word: 命令", "system": &ctx.Command{Name: "system word...", Help: []string{"调用系统命令, word: 命令",
@ -211,10 +216,10 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
if cmd, ok := info["cmd"].(*exec.Cmd); ok { if cmd, ok := info["cmd"].(*exec.Cmd); ok {
m.Add("append", "key", key) m.Add("append", "key", key)
m.Add("append", "create_time", info["create_time"]) m.Add("append", "create_time", info["create_time"])
m.Add("append", "cmd", kit.Select(cmd.Args[0], cmd.Args, 1))
m.Add("append", "log", info["log"])
m.Add("append", "pid", cmd.Process.Pid)
m.Add("append", "finish_time", info["finish_time"]) m.Add("append", "finish_time", info["finish_time"])
m.Add("append", "pid", cmd.Process.Pid)
m.Add("append", "log", info["log"])
m.Add("append", "cmd", kit.Select(cmd.Args[0], cmd.Args, 1))
if cmd.ProcessState == nil { if cmd.ProcessState == nil {
m.Add("append", "str", "") m.Add("append", "str", "")
} else { } else {
@ -298,7 +303,9 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
l, e := os.Create(m.Option("cmd_log")) l, e := os.Create(m.Option("cmd_log"))
m.Assert(e) m.Assert(e)
cmd.Stdin, cmd.Stdout, cmd.Stderr = nil, l, l l2, e := os.Create(m.Option("cmd_log") + "err")
m.Assert(e)
cmd.Stdin, cmd.Stdout, cmd.Stderr = nil, l, l2
h, _ := kit.Hash("uniq") h, _ := kit.Hash("uniq")
m.Conf("daemon", h, map[string]interface{}{ m.Conf("daemon", h, map[string]interface{}{
@ -308,10 +315,8 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
m.GoFunc(m, func(m *ctx.Message) { m.GoFunc(m, func(m *ctx.Message) {
if e := cmd.Start(); e != nil { if e := cmd.Start(); e != nil {
m.Log("fuck", "%v", e)
m.Echo("error: ").Echo("%s\n", e) m.Echo("error: ").Echo("%s\n", e)
} else if e := cmd.Wait(); e != nil { } else if e := cmd.Wait(); e != nil {
m.Log("fuck", "%v", e)
m.Echo("error: ").Echo("%s\n", e) m.Echo("error: ").Echo("%s\n", e)
} }
m.Conf("daemon", []string{h, "finish_time"}, time.Now().Format(m.Conf("time_format"))) m.Conf("daemon", []string{h, "finish_time"}, time.Now().Format(m.Conf("time_format")))

View File

@ -587,7 +587,7 @@ func (m *Message) CopyTo(msg *Message, arg ...string) *Message {
return m return m
} }
func (m *Message) Copy(msg *Message, arg ...string) *Message { func (m *Message) Copy(msg *Message, arg ...string) *Message {
if m == msg { if msg == nil || m == msg {
return m return m
} }
@ -853,6 +853,21 @@ func (m *Message) Magic(begin string, chain interface{}, args ...interface{}) in
} }
return nil return nil
} }
func (m *Message) Current(text string) string {
cs := []string{}
if pod := kit.Format(m.Magic("session", "current.pod")); pod != "" {
cs = append(cs, "context", "ssh", "sh", "node", "'"+pod+"'")
}
if ctx := kit.Format(m.Magic("session", "current.ctx")); ctx != "" {
cs = append(cs, "context", ctx)
}
if cmd := kit.Format(m.Magic("session", "current.cmd")); cmd != "" {
cs = append(cs, cmd)
}
m.Log("info", "%s %s current %v", m.Option("username"), m.Option("sessid"), cs)
cs = append(cs, text)
return strings.Join(cs, " ")
}
func (m *Message) Append(key string, arg ...interface{}) string { func (m *Message) Append(key string, arg ...interface{}) string {
if len(arg) > 0 { if len(arg) > 0 {
m.Insert(key, 0, arg...) m.Insert(key, 0, arg...)
@ -909,6 +924,7 @@ func (m *Message) Table(cbs ...interface{}) *Message {
return m return m
} }
// 遍历函数
if len(cbs) > 0 { if len(cbs) > 0 {
switch cb := cbs[0].(type) { switch cb := cbs[0].(type) {
case func(map[string]string) bool: case func(map[string]string) bool:
@ -925,32 +941,43 @@ func (m *Message) Table(cbs ...interface{}) *Message {
return m return m
case func(map[string]string): case func(map[string]string):
nrow := len(m.Meta[m.Meta["append"][0]]) nrow := len(m.Meta[m.Meta["append"][0]])
line := map[string]string{}
for i := 0; i < nrow; i++ { for i := 0; i < nrow; i++ {
line := map[string]string{}
for _, k := range m.Meta["append"] { for _, k := range m.Meta["append"] {
line[k] = m.Meta[k][i] line[k] = m.Meta[k][i]
} }
cb(line) cb(line)
} }
return m return m
case func(int, map[string]string):
nrow := len(m.Meta[m.Meta["append"][0]])
for i := 0; i < nrow; i++ {
line := map[string]string{}
for _, k := range m.Meta["append"] {
line[k] = m.Meta[k][i]
}
cb(i, line)
}
return m
} }
} }
//计算列宽 //计算列宽
space := m.Confx("table_space")
depth, width := 0, map[string]int{} depth, width := 0, map[string]int{}
for _, k := range m.Meta["append"] { for _, k := range m.Meta["append"] {
if len(m.Meta[k]) > depth { if len(m.Meta[k]) > depth {
depth = len(m.Meta[k]) depth = len(m.Meta[k])
} }
width[k] = len(k) width[k] = kit.Width(k, len(space))
for _, v := range m.Meta[k] { for _, v := range m.Meta[k] {
if len(v) > width[k] { if kit.Width(v, len(space)) > width[k] {
width[k] = len(v) width[k] = kit.Width(v, len(space))
} }
} }
} }
space := m.Confx("table_space") // 回调函数
var cb func(maps map[string]string, list []string, line int) (goon bool) var cb func(maps map[string]string, list []string, line int) (goon bool)
if len(cbs) > 0 { if len(cbs) > 0 {
cb = cbs[0].(func(maps map[string]string, list []string, line int) (goon bool)) cb = cbs[0].(func(maps map[string]string, list []string, line int) (goon bool))
@ -977,7 +1004,7 @@ func (m *Message) Table(cbs ...interface{}) *Message {
row := map[string]string{} row := map[string]string{}
wor := []string{} wor := []string{}
for _, k := range m.Meta["append"] { for _, k := range m.Meta["append"] {
row[k], wor = k, append(wor, k+strings.Repeat(space, width[k]-len(k))) row[k], wor = k, append(wor, k+strings.Repeat(space, width[k]-kit.Width(k, len(space))))
} }
if !cb(row, wor, -1) { if !cb(row, wor, -1) {
return m return m
@ -993,7 +1020,7 @@ func (m *Message) Table(cbs ...interface{}) *Message {
data = m.Meta[k][i] data = m.Meta[k][i]
} }
row[k], wor = data, append(wor, data+strings.Repeat(space, width[k]-len(data))) row[k], wor = data, append(wor, data+strings.Repeat(space, width[k]-kit.Width(data, len(space))))
} }
if !cb(row, wor, i) { if !cb(row, wor, i) {
break break
@ -1419,6 +1446,16 @@ func (m *Message) Free(cbs ...func(msg *Message) (done bool)) *Message {
return m return m
} }
func (m *Message) Cmdm(args ...interface{}) *Message {
// 执行命令
msg := m.Search(kit.Format(m.Magic("session", "current.ctx")), true)[0]
if msg == nil {
msg = m.Spawn()
}
msg.Cmd(args...).CopyTo(m)
m.Magic("session", "current.ctx", msg.target.Name)
return m
}
func (m *Message) Cmdy(args ...interface{}) *Message { func (m *Message) Cmdy(args ...interface{}) *Message {
m.Cmd(args...).CopyTo(m) m.Cmd(args...).CopyTo(m)
return m return m

View File

@ -48,10 +48,7 @@ func (mdb *MDB) Start(m *ctx.Message, arg ...string) bool {
return false return false
} }
func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool { func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool {
if mdb.DB != nil { return false
return false
}
return true
} }
var Index = &ctx.Context{Name: "mdb", Help: "数据中心", var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
@ -69,11 +66,6 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
"temp": &ctx.Config{Name: "temp", Value: map[string]interface{}{}, Help: "缓存数据"}, "temp": &ctx.Config{Name: "temp", Value: map[string]interface{}{}, Help: "缓存数据"},
"temp_view": &ctx.Config{Name: "temp_view", Value: map[string]interface{}{}, Help: "缓存数据"}, "temp_view": &ctx.Config{Name: "temp_view", Value: map[string]interface{}{}, Help: "缓存数据"},
"note_view": &ctx.Config{Name: "note_view", Value: map[string]interface{}{
"default": []interface{}{"key", "create_time", "type", "name", "model", "value"},
"base": []interface{}{"key", "create_time", "type", "name", "model", "value"},
"full": []interface{}{"key", "create_time", "access_time", "type", "name", "model", "value", "view", "data", "ship"},
}, Help: "数据视图"},
"note": &ctx.Config{Name: "note", Value: map[string]interface{}{ "note": &ctx.Config{Name: "note", Value: map[string]interface{}{
"faa01a8fc2fc92dae3fbc02ac1b4ec75": map[string]interface{}{ "faa01a8fc2fc92dae3fbc02ac1b4ec75": map[string]interface{}{
"create_time": "1990-07-30 07:08:09", "access_time": "2017-11-01 02:03:04", "create_time": "1990-07-30 07:08:09", "access_time": "2017-11-01 02:03:04",
@ -94,145 +86,13 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
}, },
}, },
}, Help: "数据结构"}, }, Help: "数据结构"},
"note_view": &ctx.Config{Name: "note_view", Value: map[string]interface{}{
"default": []interface{}{"key", "create_time", "type", "name", "model", "value"},
"base": []interface{}{"key", "create_time", "type", "name", "model", "value"},
"full": []interface{}{"key", "create_time", "access_time", "type", "name", "model", "value", "view", "data", "ship"},
}, Help: "数据视图"},
}, },
Commands: map[string]*ctx.Command{ Commands: map[string]*ctx.Command{
"temp": &ctx.Command{Name: "temp [type [meta [data]]] [tid [node|ship|data] [chain... [select ...]]]", Form: map[string]int{"select": -1, "limit": 1}, Help: "缓存数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) > 2 { // 添加数据
if temp := m.Confm("temp", arg[0]); temp == nil {
h := m.Cmdx("aaa.hash", arg[0], arg[1])
m.Confv("temp", h, map[string]interface{}{
"create_time": m.Time(), "expire_time": m.Time("60s"),
"type": arg[0], "meta": arg[1], "data": m.Optionv(arg[2]),
})
arg[2], arg = h, arg[2:]
}
}
if len(arg) > 1 {
if temp, msg := m.Confm("temp", arg[0]), m; temp != nil {
hash, arg := arg[0], arg[1:]
switch arg[0] {
case "node": // 查看节点
m.Put("option", "temp", temp).Cmdy("ctx.trans", "temp")
return
case "ship": //查看链接
for k, v := range temp {
val := v.(map[string]interface{})
m.Add("append", "key", k)
m.Add("append", "create_time", val["create_time"])
m.Add("append", "type", val["type"])
m.Add("append", "meta", val["meta"])
}
m.Sort("create_time", "time_r").Table()
return
case "data": // 查看数据
arg = arg[1:]
}
trans := strings.Join(append([]string{hash, "data"}, arg...), ".")
h := m.Cmdx("aaa.hash", "trans", trans)
if len(arg) == 0 || temp["type"].(string) == "trans" {
h = hash
} else { // 转换数据
if view := m.Confm("temp", h); view != nil && false { // 加载缓存
msg = m.Spawn()
switch data := view["data"].(type) {
case map[string][]string:
msg.Meta = data
case map[string]interface{}:
for k, v := range data {
switch val := v.(type) {
case []interface{}:
msg.Add("append", k, val)
}
}
m.Confv("temp", []string{h, "data"}, msg.Meta)
}
temp = view
} else if arg[0] == "hash" { // 添加缓存
m.Echo(hash)
} else if arg[0] == "" { // 添加缓存
b, _ := json.MarshalIndent(temp["data"], "", " ")
m.Echo(string(b))
} else {
msg = m.Put("option", "temp", temp["data"]).Cmd("ctx.trans", "temp", arg)
m.Confv("temp", h, map[string]interface{}{
"create_time": m.Time(), "expire_time": m.Time("60s"),
"type": "trans", "meta": trans, "data": msg.Meta,
"ship": map[string]interface{}{
hash: map[string]interface{}{"create_time": m.Time(), "ship": "0", "type": temp["type"], "meta": temp["meta"]},
},
})
m.Confv("temp", []string{hash, "ship", h}, map[string]interface{}{
"create_time": m.Time(), "ship": "1", "type": "trans", "meta": trans,
})
temp = m.Confm("temp", h)
}
}
if m.Options("select") { // 过滤数据
chain := strings.Join(m.Optionv("select").([]string), " ")
hh := m.Cmdx("aaa.hash", "select", chain, h)
if view := m.Confm("temp", hh); view != nil && false { // 加载缓存
msg = msg.Spawn()
switch data := view["data"].(type) {
case map[string][]string:
msg.Meta = data
case map[string]interface{}:
for k, v := range data {
switch val := v.(type) {
case []interface{}:
msg.Add("append", k, val)
}
}
m.Confv("temp", []string{h, "data"}, msg.Meta)
}
} else { // 添加缓存
msg = msg.Spawn().Copy(msg, "append").Cmd("select", m.Optionv("select"))
m.Confv("temp", hh, map[string]interface{}{
"create_time": m.Time(), "expire_time": m.Time("60s"),
"type": "select", "meta": chain, "data": msg.Meta,
"ship": map[string]interface{}{
h: map[string]interface{}{"create_time": m.Time(), "ship": "0", "type": temp["type"], "meta": temp["meta"]},
},
})
m.Confv("temp", []string{h, "ship", hh}, map[string]interface{}{
"create_time": m.Time(), "ship": "1", "type": "select", "meta": chain,
})
}
}
msg.CopyTo(m)
return
}
}
arg, h := kit.Slice(arg)
if h != "" {
if temp := m.Confm("temp", h); temp != nil {
m.Echo(h)
return
}
}
// 缓存列表
m.Confm("temp", func(key string, temp map[string]interface{}) {
if len(arg) == 0 || strings.HasPrefix(key, arg[0]) || strings.HasSuffix(key, arg[0]) || (temp["type"].(string) == arg[0] && (len(arg) == 1 || strings.Contains(temp["meta"].(string), arg[1]))) {
m.Add("append", "key", key)
m.Add("append", "create_time", temp["create_time"])
m.Add("append", "type", temp["type"])
m.Add("append", "meta", temp["meta"])
}
})
m.Sort("create_time", "time_r").Table().Cmd("select", m.Optionv("select"))
return
}},
"open": &ctx.Command{Name: "open [database [username [password [address [protocol [driver]]]]]]", "open": &ctx.Command{Name: "open [database [username [password [address [protocol [driver]]]]]]",
Help: "打开数据库, database: 数据库名, username: 用户名, password: 密码, address: 服务地址, protocol: 服务协议, driver: 数据库类型", Help: "打开数据库, database: 数据库名, username: 用户名, password: 密码, address: 服务地址, protocol: 服务协议, driver: 数据库类型",
Form: map[string]int{"dbname": 1, "dbhelp": 1}, Form: map[string]int{"dbname": 1, "dbhelp": 1},
@ -452,49 +312,174 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
m.Cmdy(".query", strings.Join(stmt, " ")) m.Cmdy(".query", strings.Join(stmt, " "))
return return
}}, }},
"update": &ctx.Command{Name: "update table condition [set field value]", Help: "修改数据, table: 关系表, condition: 条件语句, set: 修改数据", "update": &ctx.Command{Name: "update [table [condition [field [value]]...]]",
Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool { Help: "修改数据, table: 关系表, condition: 条件语句, field: 字段名, value: 字段值",
if len(arg) == 0 {
m.Put("option", "auto_cmd", "").Spawn().Cmd("query", "show tables").Table(func(line map[string]string) {
for _, v := range line {
m.Auto(v, "", "")
}
})
return true
}
if len(arg) == 2 {
// m.Put("option", "auto_cmd", "").Spawn().Cmd("show", arg[0], "where", arg[1]).Table(func(line map[string]string) {
// for _, v := range line {
// m.Auto(v, "", "")
// }
// })
return true
}
return true
},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 2 { switch len(arg) {
m.Cmd(".show", arg[0], "where", arg[1]).CopyTo(m, "append") case 0:
m.Cmdy(".show")
case 1:
m.Cmdy(".show", arg[0])
case 2:
m.Cmdy(".show", arg[0], "where", arg[1])
case 3:
m.Cmdy(".show", arg[0], arg[2], "where", arg[1])
default:
fields := []string{}
values := []string{}
for i := 2; i < len(arg)-1; i += 2 {
fields = append(fields, arg[i])
values = append(values, fmt.Sprintf("%s='%s'", arg[i], arg[i+1]))
}
stmt := []string{fmt.Sprintf("update %s", arg[0])}
stmt = append(stmt, "set", strings.Join(values, ","))
stmt = append(stmt, fmt.Sprintf("where %s", arg[1]))
m.Cmd(".exec", strings.Join(stmt, " "))
m.Cmdy("show", arg[0], fields, "where", arg[1])
} }
fields := []string{}
values := []string{}
for i := 3; i < len(arg)-1; i += 2 {
fields = append(fields, arg[i])
values = append(values, fmt.Sprintf("%s='%s'", arg[i], arg[i+1]))
}
stmt := []string{fmt.Sprintf("update %s", arg[0])}
stmt = append(stmt, "set", strings.Join(values, ","))
stmt = append(stmt, fmt.Sprintf("where %s", arg[1]))
m.Cmd(".exec", strings.Join(stmt, " "))
m.Cmdy("show", arg[0], fields, "where", arg[1])
return return
}}, }},
"temp": &ctx.Command{Name: "temp [type [meta [data]]] [tid [node|ship|data] [chain... [select ...]]]", Form: map[string]int{"select": -1, "limit": 1}, Help: "缓存数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) > 2 { // 添加数据
if temp := m.Confm("temp", arg[0]); temp == nil {
h := m.Cmdx("aaa.hash", arg[0], arg[1])
m.Confv("temp", h, map[string]interface{}{
"create_time": m.Time(), "expire_time": m.Time("60s"),
"type": arg[0], "meta": arg[1], "data": m.Optionv(arg[2]),
})
arg[2], arg = h, arg[2:]
}
}
if len(arg) > 1 {
if temp, msg := m.Confm("temp", arg[0]), m; temp != nil {
hash, arg := arg[0], arg[1:]
switch arg[0] {
case "node": // 查看节点
m.Put("option", "temp", temp).Cmdy("ctx.trans", "temp")
return
case "ship": //查看链接
for k, v := range temp {
val := v.(map[string]interface{})
m.Add("append", "key", k)
m.Add("append", "create_time", val["create_time"])
m.Add("append", "type", val["type"])
m.Add("append", "meta", val["meta"])
}
m.Sort("create_time", "time_r").Table()
return
case "data": // 查看数据
arg = arg[1:]
}
trans := strings.Join(append([]string{hash, "data"}, arg...), ".")
h := m.Cmdx("aaa.hash", "trans", trans)
if len(arg) == 0 || temp["type"].(string) == "trans" {
h = hash
} else { // 转换数据
if view := m.Confm("temp", h); view != nil && false { // 加载缓存
msg = m.Spawn()
switch data := view["data"].(type) {
case map[string][]string:
msg.Meta = data
case map[string]interface{}:
for k, v := range data {
switch val := v.(type) {
case []interface{}:
msg.Add("append", k, val)
}
}
m.Confv("temp", []string{h, "data"}, msg.Meta)
}
temp = view
} else if arg[0] == "hash" { // 添加缓存
m.Echo(hash)
} else if arg[0] == "" { // 添加缓存
b, _ := json.MarshalIndent(temp["data"], "", " ")
m.Echo(string(b))
} else {
msg = m.Put("option", "temp", temp["data"]).Cmd("ctx.trans", "temp", arg)
m.Confv("temp", h, map[string]interface{}{
"create_time": m.Time(), "expire_time": m.Time("60s"),
"type": "trans", "meta": trans, "data": msg.Meta,
"ship": map[string]interface{}{
hash: map[string]interface{}{"create_time": m.Time(), "ship": "0", "type": temp["type"], "meta": temp["meta"]},
},
})
m.Confv("temp", []string{hash, "ship", h}, map[string]interface{}{
"create_time": m.Time(), "ship": "1", "type": "trans", "meta": trans,
})
temp = m.Confm("temp", h)
}
}
if m.Options("select") { // 过滤数据
chain := strings.Join(m.Optionv("select").([]string), " ")
hh := m.Cmdx("aaa.hash", "select", chain, h)
if view := m.Confm("temp", hh); view != nil && false { // 加载缓存
msg = msg.Spawn()
switch data := view["data"].(type) {
case map[string][]string:
msg.Meta = data
case map[string]interface{}:
for k, v := range data {
switch val := v.(type) {
case []interface{}:
msg.Add("append", k, val)
}
}
m.Confv("temp", []string{h, "data"}, msg.Meta)
}
} else { // 添加缓存
msg = msg.Spawn().Copy(msg, "append").Cmd("select", m.Optionv("select"))
m.Confv("temp", hh, map[string]interface{}{
"create_time": m.Time(), "expire_time": m.Time("60s"),
"type": "select", "meta": chain, "data": msg.Meta,
"ship": map[string]interface{}{
h: map[string]interface{}{"create_time": m.Time(), "ship": "0", "type": temp["type"], "meta": temp["meta"]},
},
})
m.Confv("temp", []string{h, "ship", hh}, map[string]interface{}{
"create_time": m.Time(), "ship": "1", "type": "select", "meta": chain,
})
}
}
msg.CopyTo(m)
return
}
}
arg, h := kit.Slice(arg)
if h != "" {
if temp := m.Confm("temp", h); temp != nil {
m.Echo(h)
return
}
}
// 缓存列表
m.Confm("temp", func(key string, temp map[string]interface{}) {
if len(arg) == 0 || strings.HasPrefix(key, arg[0]) || strings.HasSuffix(key, arg[0]) || (temp["type"].(string) == arg[0] && (len(arg) == 1 || strings.Contains(temp["meta"].(string), arg[1]))) {
m.Add("append", "key", key)
m.Add("append", "create_time", temp["create_time"])
m.Add("append", "type", temp["type"])
m.Add("append", "meta", temp["meta"])
}
})
m.Sort("create_time", "time_r").Table().Cmd("select", m.Optionv("select"))
return
}},
"note": &ctx.Command{Name: "note [model [name [type name]...]]|[index [name data...]]|[value name data...]|[name model data...]", "note": &ctx.Command{Name: "note [model [name [type name]...]]|[index [name data...]]|[value name data...]|[name model data...]",
Form: map[string]int{"offset": 1, "limit": 1}, Help: "记事", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { Form: map[string]int{"begin": 2, "offset": 1, "limit": 1}, Help: "记事", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
offset := kit.Int(kit.Select(m.Conf("page_offset"), m.Option("offset"))) offset := kit.Int(kit.Select(m.Conf("page_offset"), m.Option("offset")))
limit := kit.Int(kit.Select(m.Conf("page_limit"), m.Option("limit"))) limit := kit.Int(kit.Select(m.Conf("page_limit"), m.Option("limit")))
@ -574,6 +559,21 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
values[kit.Format(model["name"])] = v values[kit.Format(model["name"])] = v
}) })
miss := false
if m.Has("begin") {
for i := 0; i < len(m.Meta["begin"]); i += 2 {
if !strings.HasPrefix(kit.Select(kit.Format(note[m.Meta["begin"][i]]),
kit.Format(values[m.Meta["begin"][i]])), m.Meta["begin"][i+1]) {
miss = true
break
}
}
}
if miss {
i--
continue
}
for i := 0; i < len(fields); i++ { for i := 0; i < len(fields); i++ {
switch fields[i] { switch fields[i] {
case "key": case "key":
@ -679,12 +679,12 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
case "value": case "value":
hi := m.Cmdx("mdb.note", "index", arg[1]) hi := m.Cmdx("mdb.note", "index", arg[1])
hv, _ := kit.Hash("type", arg[0], "name", arg[1], "data", arg[2:]) hv, _ := kit.Hash("type", arg[0], "name", arg[1], "data", arg[2])
if value := m.Confm("note", hv); value == nil { if value := m.Confm("note", hv); value == nil {
prev := m.Conf("note", []string{hi, "ship", "value", "data"}) prev := m.Conf("note", []string{hi, "ship", "value", "data"})
m.Confv("note", hv, map[string]interface{}{ m.Confv("note", hv, map[string]interface{}{
"create_time": m.Time(), "access_time": m.Time(), "create_time": m.Time(), "access_time": m.Time(),
"type": arg[0], "name": arg[1], "data": arg[2:], "ship": map[string]interface{}{ "type": arg[0], "name": arg[1], "data": arg[2], "ship": map[string]interface{}{
"prev": map[string]interface{}{"type": "value", "data": prev}, "prev": map[string]interface{}{"type": "value", "data": prev},
"index": map[string]interface{}{"type": "index", "data": hi}, "index": map[string]interface{}{"type": "index", "data": hi},
"note": map[string]interface{}{"type": "note", "data": ""}, "note": map[string]interface{}{"type": "note", "data": ""},

View File

@ -38,6 +38,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
}, },
Configs: map[string]*ctx.Config{ Configs: map[string]*ctx.Config{
"node": &ctx.Config{Name: "node", Value: map[string]interface{}{}, Help: "主机信息"}, "node": &ctx.Config{Name: "node", Value: map[string]interface{}{}, Help: "主机信息"},
"trust": &ctx.Config{Name: "trust", Value: map[string]interface{}{}, Help: "主机信息"},
"current": &ctx.Config{Name: "current", Value: "", Help: "当前主机"}, "current": &ctx.Config{Name: "current", Value: "", Help: "当前主机"},
"timer": &ctx.Config{Name: "timer", Value: "", Help: "断线重连"}, "timer": &ctx.Config{Name: "timer", Value: "", Help: "断线重连"},
"timer_interval": &ctx.Config{Name: "timer_interval", Value: "10s", Help: "断线重连"}, "timer_interval": &ctx.Config{Name: "timer_interval", Value: "10s", Help: "断线重连"},
@ -58,6 +59,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
"remote": &ctx.Command{Name: "remote auto|dial|listen args...", Help: "远程连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "remote": &ctx.Command{Name: "remote auto|dial|listen args...", Help: "远程连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 { if len(arg) == 0 {
m.Cmdy("ctx.config", "node", "format", "table") m.Cmdy("ctx.config", "node", "format", "table")
m.Meta["append"] = []string{"key", "type", "create_time"}
return return
} }
@ -96,24 +98,19 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
m.Conf("timer", m.Cmdx("cli.timer", "delete", m.Conf("timer"))) m.Conf("timer", m.Cmdx("cli.timer", "delete", m.Conf("timer")))
} }
msg := m.Spawn(nfs.Target()) m.Spawn(nfs.Target()).Call(func(node *ctx.Message) *ctx.Message {
if m.Confs("runtime", "user.cert") { // 添加网关
msg.Option("user.route", kit.Select(m.Conf("runtime", "user.route"), m.Conf("runtime", "user.route")))
}
msg.Call(func(node *ctx.Message) *ctx.Message {
// 添加主机
m.Confv("node", node.Append("node.name"), map[string]interface{}{ m.Confv("node", node.Append("node.name"), map[string]interface{}{
"module": m.Cap("stream", nfs.Format("target")), "module": m.Cap("stream", nfs.Format("target")),
"create_time": m.Time(), "create_time": m.Time(),
"type": "master", "type": "master",
"node": map[string]interface{}{ "name": node.Append("node.name"),
"name": node.Append("node.name"),
"type": "master",
},
}) })
// 机路由 // 本机路由
m.Conf("runtime", "node.route", node.Append("node.route")+"."+node.Result(0)) m.Conf("runtime", "node.route", node.Append("node.route")+"."+node.Result(0))
// 本机用户
if !m.Confs("runtime", "user.route") { if !m.Confs("runtime", "user.route") {
if m.Confs("runtime", "user.cert") && m.Confs("runtime", "user.key") { if m.Confs("runtime", "user.cert") && m.Confs("runtime", "user.key") {
m.Cmd("ssh.share", "root", m.Conf("runtime", "node.route")) m.Cmd("ssh.share", "root", m.Conf("runtime", "node.route"))
@ -121,15 +118,12 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
m.Cmd("ssh.share", "root", node.Append("user.route")) m.Cmd("ssh.share", "root", node.Append("user.route"))
} }
} }
// 网关用户
if !node.Appends("user.route") { if !node.Appends("user.route") {
m.Cmd("ssh.share", node.Append("node.route"), "root", m.Conf("runtime", "node.route")) m.Cmd("ssh.share", node.Append("node.route"), "root", m.Conf("runtime", "node.route"))
} }
// 默认节点
if !m.Confs("current") {
m.Conf("current", node.Append("node.name"))
}
// 清理主机 // 清理主机
nfs.Free(func(nfs *ctx.Message) bool { nfs.Free(func(nfs *ctx.Message) bool {
m.Conf("timer", m.Cmdx("cli.timer", "repeat", m.Conf("timer_interval"), "context", "ssh", "remote", "redial", arg[1:])) m.Conf("timer", m.Cmdx("cli.timer", "repeat", m.Conf("timer_interval"), "context", "ssh", "remote", "redial", arg[1:]))
@ -153,25 +147,12 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
name = fmt.Sprintf("%s_%d", arg[2], m.Capi("nnode", 1)) name = fmt.Sprintf("%s_%d", arg[2], m.Capi("nnode", 1))
} }
info := map[string]string{}
if len(arg) > 4 && m.Cmds("aaa.rsa", "check", m.Conf("runtime", "node.cert"), arg[4]) {
m.Cmd("aaa.rsa", "info", arg[4]).Table(func(line map[string]string) {
for k, v := range line {
info[k] = v
}
})
}
m.Log("info", "info--- %v", info)
// 添加节点 // 添加节点
m.Confv("node", name, map[string]interface{}{ m.Confv("node", name, map[string]interface{}{
"module": m.Format("source"), "module": m.Format("source"),
"create_time": m.Time(), "create_time": m.Time(),
"type": arg[3], "type": arg[3],
"node": map[string]interface{}{ "name": name,
"name": name,
"type": arg[3],
},
}) })
// 节点路由 // 节点路由
@ -181,11 +162,6 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
m.Append("node.name", m.Conf("runtime", "node.name")) m.Append("node.name", m.Conf("runtime", "node.name"))
m.Echo(name).Back(m) m.Echo(name).Back(m)
// 默认节点
if !m.Confs("current") {
m.Conf("current", name)
}
// 清理节点 // 清理节点
m.Sess("ms_source", false).Free(func(msg *ctx.Message) bool { m.Sess("ms_source", false).Free(func(msg *ctx.Message) bool {
m.Log("info", "delete node %s", name) m.Log("info", "delete node %s", name)
@ -235,6 +211,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
// 设备签名 // 设备签名
m.Option("node.sign", m.Cmdx("aaa.rsa", "sign", m.Conf("runtime", "node.key"), m.Option("text.hash", hash))) m.Option("node.sign", m.Cmdx("aaa.rsa", "sign", m.Conf("runtime", "node.key"), m.Option("text.hash", hash)))
// 用户签名 // 用户签名
if m.Options("user.sign") && m.Confs("runtime", "user.key") { if m.Options("user.sign") && m.Confs("runtime", "user.key") {
m.Option("user.sign", m.Cmdx("aaa.rsa", "sign", m.Conf("runtime", "user.key"), m.Option("text.hash", hash))) m.Option("user.sign", m.Cmdx("aaa.rsa", "sign", m.Conf("runtime", "user.key"), m.Option("text.hash", hash)))
@ -317,20 +294,6 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
} }
switch arg[0] { switch arg[0] {
case "login": // 用户代理
if !m.Cmds("aaa.auth", "proxy", m.Option("node.route")) {
return
}
sess := m.Cmd("aaa.auth", "username", m.Option("user.name"), "session", "proxy").Append("key")
if sess == "" {
sess = m.Cmdx("aaa.sess", "proxy", "username", m.Option("user.name"))
}
m.Cmd("aaa.auth", sess, "proxy", m.Option("node.route"))
m.Echo(sess)
return
case "share": // 设备权限 case "share": // 设备权限
// 默认用户 // 默认用户
if !m.Confs("runtime", "user.route") { if !m.Confs("runtime", "user.route") {
@ -372,29 +335,51 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
m.Cmd("aaa.auth", sess, "share", user.Append("user.route")) m.Cmd("aaa.auth", sess, "share", user.Append("user.route"))
} }
return return
case "login": // 用户代理
if !m.Cmds("aaa.auth", "proxy", m.Option("node.route")) {
return
}
sess := m.Cmd("aaa.auth", "username", m.Option("user.name"), "session", "proxy").Append("key")
if sess == "" {
sess = m.Cmdx("aaa.sess", "proxy", "username", m.Option("user.name"))
}
m.Cmd("aaa.auth", sess, "proxy", m.Option("node.route"))
m.Echo(sess)
return
} }
// 检查会话
m.Option("sessid", "")
m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "session").Table(func(line map[string]string) {
if m.Cmds("aaa.auth", line["key"], "username", m.Option("user.name")) {
m.Option("sessid", line["key"])
}
})
if m.Options("remote_code") { if m.Options("remote_code") {
if !m.Options("sessid") { m.Option("username", m.Option("user.name"))
// 用户签名
hash, _ := kit.Hash("rand", m.Option("text.time", m.Time("stamp")), m.Option("node.route"))
m.Option("user.cert", m.Cmd("aaa.auth", "username", m.Option("user.name"), "cert").Append("meta"))
m.Option("user.sign", m.Spawn().Cmdx("ssh.remote", m.Option("user.route"), "sync", "check", "user", m.Option("node.route"), hash))
// 代理验签 // 检查会话
if !m.Options("user.cert") || !m.Options("user.sign") || !m.Cmds("aaa.rsa", "verify", m.Option("user.cert"), m.Option("user.sign"), hash) { m.Option("sessid", "")
m.Log("warn", "user error") m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "session").Table(func(line map[string]string) {
m.Echo("no right of %s", m.Option("text.route")) if m.Cmds("aaa.auth", line["key"], "username", m.Option("user.name")) {
return m.Option("sessid", line["key"])
} }
})
if !m.Options("sessid") {
if !m.Confs("trust", m.Option("node.route")) {
// 用户签名
hash, _ := kit.Hash("rand", m.Option("text.time", m.Time("stamp")), m.Option("node.route"))
m.Option("user.cert", m.Cmd("aaa.auth", "username", m.Option("user.name"), "cert").Append("meta"))
m.Option("user.sign", m.Spawn().Cmdx("ssh.remote", m.Option("user.route"), "sync", "check", "user", m.Option("node.route"), hash))
// 代理验签
if !m.Options("user.cert") || !m.Options("user.sign") || !m.Cmds("aaa.rsa", "verify", m.Option("user.cert"), m.Option("user.sign"), hash) {
m.Log("warn", "user error")
m.Echo("no right of %s", m.Option("text.route"))
return
}
} else {
m.Log("info", "skip verify user %s", m.Option("user.name"))
}
// 创建会话 // 创建会话
m.Option("sessid", m.Cmdx("aaa.sess", "nodes", "username", m.Option("user.name"))) m.Option("sessid", m.Cmdx("aaa.sess", "nodes", "username", m.Option("user.name")))
m.Cmd("aaa.auth", m.Option("sessid"), "nodes", m.Option("node.route")) m.Cmd("aaa.auth", m.Option("sessid"), "nodes", m.Option("node.route"))
@ -404,27 +389,54 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
if m.Option("bench", m.Cmd("aaa.sess", m.Option("sessid"), "bench").Append("key")); !m.Options("bench") { if m.Option("bench", m.Cmd("aaa.sess", m.Option("sessid"), "bench").Append("key")); !m.Options("bench") {
m.Option("bench", m.Cmdx("aaa.work", m.Option("sessid"), "nodes")) m.Option("bench", m.Cmdx("aaa.work", m.Option("sessid"), "nodes"))
} }
// 权限检查
if !m.Cmds("aaa.work", m.Option("bench"), "right", m.Option("user.name"), "remote", arg[0]) {
m.Echo("no right %s %s", "remote", arg[0])
return
}
} }
if !m.Options("remote_code") || m.Cmds("aaa.work", m.Option("bench"), "right", m.Option("user.name"), "remote", arg[0]) { // 执行命令
m.Option("username", m.Option("user.name")) m.Cmdm(arg)
m.Option("current_ctx", kit.Select("ssh", m.Cmdx("aaa.auth", m.Option("bench"), "data", "target")))
// 执行命令
msg := m.Find(m.Option("current_ctx")).Cmd(arg).CopyTo(m)
m.Cmd("aaa.auth", m.Option("bench"), "data", "target", msg.Cap("module"))
} else {
m.Echo("no right %s %s", "remote", arg[0])
}
} }
return return
}}, }},
"share": &ctx.Command{Name: "share [serve.route] role client.route...", Help: "共享权限", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
m.Cmd("aaa.auth", "apply").Table(func(node map[string]string) {
m.Cmd("aaa.auth", node["key"], "session", "apply").Table(func(sess map[string]string) {
m.Cmd("aaa.auth", sess["key"], "username").Table(func(user map[string]string) {
m.Add("append", "time", sess["create_time"])
m.Add("append", "user", user["meta"])
m.Add("append", "node", node["meta"])
})
})
})
m.Table()
return
}
// 本地用户
if len(arg) == 2 {
m.Option("user.route", arg[1])
m.Cmd("ssh.remote", "", "share", arg[1:])
return
}
// 远程用户
m.Option("user.sign", "yes")
m.Cmd("ssh.remote", arg[0], "sync", "share", arg[1:])
return
}},
"proxy": &ctx.Command{Name: "proxy [proxy.route]", Help: "代理节点", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "proxy": &ctx.Command{Name: "proxy [proxy.route]", Help: "代理节点", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 { if len(arg) == 0 {
m.Cmd("aaa.auth", "proxy") m.Cmdy("aaa.auth", "proxy")
return return
} }
if !m.Cmds("aaa.auth", "proxy", arg[0], "session") { if !m.Cmds("aaa.auth", "proxy", arg[0], "session") {
m.Cmd("aaa.sess", "proxy", "proxy", arg[0]) m.Cmdy("aaa.sess", "proxy", "proxy", arg[0])
} }
return return
}}, }},
@ -448,39 +460,13 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
m.Echo(sess) m.Echo(sess)
return return
}}, }},
"share": &ctx.Command{Name: "share serve.route role client.route...", Help: "共享权限", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
m.Cmd("aaa.auth", "apply").Table(func(node map[string]string) {
m.Cmd("aaa.auth", node["key"], "session", "apply").Table(func(sess map[string]string) {
m.Cmd("aaa.auth", sess["key"], "username").Table(func(user map[string]string) {
m.Add("append", "time", sess["create_time"])
m.Add("append", "user", user["meta"])
m.Add("append", "node", node["meta"])
})
})
})
m.Table()
return
}
if len(arg) == 2 {
m.Option("user.route", arg[1])
m.Cmd("ssh.remote", "", "share", arg[1:])
return
}
m.Option("user.sign", "yes")
m.Cmd("ssh.remote", arg[0], "sync", "share", arg[1:])
return
}},
"check": &ctx.Command{Name: "check proxy.route client.route", Help: "权限检查", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
return
}},
"sh": &ctx.Command{Name: "sh [[node] name] cmd...", Help: "发送命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "sh": &ctx.Command{Name: "sh [[node] name] cmd...", Help: "发送命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 { if len(arg) == 0 {
m.Echo(m.Conf("current")) m.Cmdy("ssh.remote")
return return
} }
if arg[0] == "sub" { if arg[0] == "sub" {
m.Confm("node", func(name string, node map[string]interface{}) { m.Confm("node", func(name string, node map[string]interface{}) {
if node["type"] == "master" { if node["type"] == "master" {
@ -570,12 +556,6 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
} }
return return
}}, }},
"sync": &ctx.Command{Name: "sync", Help: "同步数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Confm("node", func(name string, node map[string]string) {
})
return
}},
}, },
} }

View File

@ -837,7 +837,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
return return
} }
sessid, username := m.Option("sessid"), m.Option("username") username, sessid := m.Option("username"), m.Option("sessid")
switch arg[0] { switch arg[0] {
case "login": case "login":
@ -849,8 +849,11 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
if username == "" || !m.Options(arg[1]) { if username == "" || !m.Options(arg[1]) {
break break
} }
if sessid == "" || !m.Cmds("aaa.sess", sessid) { // 创建会话 if sessid == "" || !m.Cmds("aaa.sess", sessid) { // 创建会话
sessid = m.Cmdx("aaa.sess", "web", "ip", m.Option("remote_ip")) if sessid = m.Cmd("aaa.auth", "username", m.Option("username"), "session", "web").Append("key"); sessid == "" {
sessid = m.Cmdx("aaa.sess", "web", "ip", m.Option("remote_ip"))
}
} }
if m.Cmds("aaa.sess", sessid, m.Option("username"), arg[1], m.Option(arg[1])) { // 用户登录 if m.Cmds("aaa.sess", sessid, m.Option("username"), arg[1], m.Option(arg[1])) { // 用户登录
m.Echo(sessid) m.Echo(sessid)
@ -887,6 +890,8 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
return return
} }
m.Option("current_ctx", kit.Select(m.Option("current_ctx", kit.Format(m.Magic("session", "current.ctx")))))
if web, ok := m.Target().Server.(*WEB); m.Assert(ok) { if web, ok := m.Target().Server.(*WEB); m.Assert(ok) {
// 响应类型 // 响应类型
accept_json := strings.HasPrefix(m.Option("accept"), "application/json") accept_json := strings.HasPrefix(m.Option("accept"), "application/json")
@ -944,6 +949,9 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
// 添加参数值 // 添加参数值
args := []string{val["componet_cmd"].(string)} args := []string{val["componet_cmd"].(string)}
if kit.Right(val["componet_pod"]) {
args = []string{"sh", "node", kit.Format(m.Magic("session", "current.pod")), val["componet_cmd"].(string)}
}
if val["arguments"] != nil { if val["arguments"] != nil {
for _, v := range val["arguments"].([]interface{}) { for _, v := range val["arguments"].([]interface{}) {
switch value := v.(type) { switch value := v.(type) {
@ -990,6 +998,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
// args = kit.Trans(list) // args = kit.Trans(list)
} }
m.Log("fuck", "what %v", args)
if msg.Cmd(args); m.Options("bench") { if msg.Cmd(args); m.Options("bench") {
name_alias := "action." + kit.Select(msg.Option("componet_name"), msg.Option("componet_name_alias")) name_alias := "action." + kit.Select(msg.Option("componet_name"), msg.Option("componet_name_alias"))

View File

@ -142,8 +142,16 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心",
}, },
}, },
}, },
map[string]interface{}{"name": "pod", "help": "pod", "template": "componet",
"componet_ctx": "ssh", "componet_cmd": "remote",
"inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": ""},
map[string]interface{}{"type": "button", "value": "refresh"},
},
"pre_run": true, "display_result": "",
},
map[string]interface{}{"name": "ctx", "help": "ctx", "template": "componet", map[string]interface{}{"name": "ctx", "help": "ctx", "template": "componet",
"componet_ctx": "cli.shy", "componet_cmd": "context", "arguments": []interface{}{"@ctx", "list"}, "componet_pod": "true", "componet_ctx": "ssh", "componet_cmd": "context", "arguments": []interface{}{"@ctx", "list"},
"display_result": "", "display_result": "",
"inputs": []interface{}{ "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "ctx", "value": ""}, map[string]interface{}{"type": "text", "name": "ctx", "value": ""},
@ -194,14 +202,14 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心",
// "pre_run": true, // "pre_run": true,
// "display_result": "", // "display_result": "",
// }, // },
map[string]interface{}{"name": "runtime", "help": "runtime", "template": "componet", // map[string]interface{}{"name": "runtime", "help": "runtime", "template": "componet",
"componet_ctx": "cli", "componet_cmd": "runtime", // "componet_ctx": "cli", "componet_cmd": "runtime",
"inputs": []interface{}{ // "inputs": []interface{}{
map[string]interface{}{"type": "button", "value": "refresh"}, // map[string]interface{}{"type": "button", "value": "refresh"},
}, // },
"pre_run": true, // "pre_run": true,
"display_result": "", // "display_result": "",
}, // },
// map[string]interface{}{"name": "sysinfo", "help": "sysinfo", "template": "componet", // map[string]interface{}{"name": "sysinfo", "help": "sysinfo", "template": "componet",
// "componet_ctx": "cli", "componet_cmd": "sysinfo", // "componet_ctx": "cli", "componet_cmd": "sysinfo",
// "inputs": []interface{}{ // "inputs": []interface{}{

View File

@ -32,6 +32,9 @@ func Log(action string, str string, args ...interface{}) {
fmt.Fprintln(os.Stderr) fmt.Fprintln(os.Stderr)
} }
func Width(str string, mul int) int {
return len([]rune(str)) + (len(str)-len([]rune(str)))/2/mul
}
func Int(arg ...interface{}) int { func Int(arg ...interface{}) int {
result := 0 result := 0
for _, v := range arg { for _, v := range arg {

View File

@ -239,7 +239,7 @@ function send_command(form, cb) {
for (var i = 0; i < nrow; i ++) { for (var i = 0; i < nrow; i ++) {
var tr = append_child(append, "tr") var tr = append_child(append, "tr")
for (var k in msg.append) { for (var k in msg.append) {
append_child(tr, "td", msg[msg.append[k]][i]) append_child(tr, "td", format(msg[msg.append[k]][i]))
} }
} }
@ -707,6 +707,28 @@ function init_download(event) {
}) })
} }
function init_contain() {
var option = document.querySelector("form.option.pod")
var append = document.querySelector("table.append.pod")
if (!append) {return}
function change(pod) {
option["pod"].value = pod
context.Cookie("current_pod", option["pod"].value)
context.GET("", {
"componet_group": "index",
"componet_name": "cmd",
"cmd": "sess current pod "+option["pod"].value,
})
return pod
}
add_sort(append, "key", function(event) {
change(event.target.innerText.trim())
})
option["pod"].value = context.Cookie("current_pod")
}
function init_context() { function init_context() {
var option = document.querySelector("form.option.ctx") var option = document.querySelector("form.option.ctx")
var append = document.querySelector("table.append.ctx") var append = document.querySelector("table.append.ctx")
@ -716,6 +738,11 @@ function init_context() {
option["ctx"].value = ctx option["ctx"].value = ctx
send_command(option) send_command(option)
context.Cookie("current_ctx", option["ctx"].value) context.Cookie("current_ctx", option["ctx"].value)
context.GET("", {
"componet_group": "index",
"componet_name": "cmd",
"cmd": "sess current ctx "+option["ctx"].value,
})
return ctx return ctx
} }
@ -912,6 +939,7 @@ window.onload = function() {
init_userinfo() init_userinfo()
init_download() init_download()
init_contain()
init_context() init_context()
init_command() init_command()
init_toolkit() init_toolkit()

View File

@ -221,6 +221,12 @@ function insert_button(which, value, callback) {
}) })
} }
function format(str) {
if (str.indexOf("http") == 0 && str.indexOf("<a href") == -1) {
return "<a href='"+str+"' target='_blank'>"+str+"</a>"
}
return str
}
function sort_table(table, index, sort_asc) { function sort_table(table, index, sort_asc) {
var list = table.querySelectorAll("tr") var list = table.querySelectorAll("tr")
var new_list = [] var new_list = []

View File

@ -366,10 +366,6 @@ function wopen(event) {
}}) }})
} }
</script> </script>
<button onclick="scan(this)">scan</button>
<button onclick="choose(this)">choose</button>
<button onclick="close(this)">close</button>
<button onclick="wopen(this)">openaddress</button>
{{end}} {{end}}
{{define "tail"}} {{define "tail"}}