diff --git a/base/cli/cli.go b/base/cli/cli.go index f8917f01..98761c93 100644 --- a/base/cli/cli.go +++ b/base/cli/cli.go @@ -49,8 +49,9 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块", m.Conf(RUNTIME, "host.pid", os.Getpid()) // 启动信息 - if user, e := user.Current(); e == nil { - m.Conf(RUNTIME, "boot.username", path.Base(kit.Select(user.Name, os.Getenv("USER")))) + m.Conf(RUNTIME, "boot.username", os.Getenv("USER")) + if user, e := user.Current(); e == nil && user.Name != "" { + m.Conf(RUNTIME, "boot.username", user.Name) } if name, e := os.Hostname(); e == nil { m.Conf(RUNTIME, "boot.hostname", kit.Select(name, os.Getenv("HOSTNAME"))) diff --git a/base/gdb/gdb.go b/base/gdb/gdb.go index e287cd3a..5964c849 100644 --- a/base/gdb/gdb.go +++ b/base/gdb/gdb.go @@ -61,7 +61,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool { // 异步事件 m.Logs(EVENT, d[0], d[1:]) m.Grows(EVENT, d[0], "", "", func(index int, value map[string]interface{}) { - m.Cmd(value["cmd"], d[1:]).Cost("event %v", d) + m.Cmd(value["cmd"], d).Cost("event %v", d) }) } } @@ -86,6 +86,23 @@ const ( MISS_CREATE = "miss.create" MIND_CREATE = "mind.create" ) + +const ( + INIT = "init" + AUTO = "auto" + MAKE = "make" + + OPEN = "open" + CLOSE = "close" + START = "start" + STOP = "stop" + + RESTART = "restart" + CHANGE = "change" + PRUNE = "prune" + CLEAR = "clear" +) + const ( LISTEN = "listen" ACTION = "action" diff --git a/base/web/dream.go b/base/web/dream.go index 3e74e484..9303b0bd 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -4,6 +4,7 @@ import ( ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/gdb" + "github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/nfs" kit "github.com/shylinux/toolkits" @@ -18,10 +19,13 @@ func _dream_list(m *ice.Message) { m.Cmdy(nfs.DIR, m.Conf(DREAM, "meta.path"), "time name").Table(func(index int, value map[string]string, head []string) { if m.Richs(SPACE, nil, value[kit.MDB_NAME], func(key string, value map[string]interface{}) { m.Push(kit.MDB_TYPE, value[kit.MDB_TYPE]) - m.Push(kit.MDB_STATUS, "start") + m.Push(kit.MDB_STATUS, gdb.START) }) == nil { m.Push(kit.MDB_TYPE, "none") - m.Push(kit.MDB_STATUS, "stop") + m.Push(kit.MDB_STATUS, gdb.STOP) + } + for _, k := range []string{"start", "stop", "restart"} { + m.Push(k, m.Cmdx(mdb.RENDER, RENDER.Button, k)) } }) m.Sort(kit.MDB_NAME) @@ -34,52 +38,96 @@ func _dream_show(m *ice.Message, name string) { // 创建目录 p := path.Join(m.Conf(DREAM, "meta.path"), name) - os.MkdirAll(p, 0777) + os.MkdirAll(p, ice.MOD_DIR) + + miss := path.Join(p, "etc/miss.sh") + if _, e := os.Stat(miss); e != nil { + m.Cmd(nfs.SAVE, miss, m.Conf(DREAM, "meta.miss")) + } if b, e := ioutil.ReadFile(path.Join(p, m.Conf(gdb.SIGNAL, "meta.pid"))); e == nil { if s, e := os.Stat("/proc/" + string(b)); e == nil && s.IsDir() { m.Info("already exists %v", string(b)) + // 已经启动 return } } if m.Richs(SPACE, nil, name, nil) == nil { // 启动任务 - m.Option(cli.CMD_TYPE, "daemon") m.Option(cli.CMD_DIR, p) - m.Optionv(cli.CMD_ENV, + m.Option(cli.CMD_STDERR, path.Join(p, m.Conf(DREAM, "meta.env.ctx_log"))) + m.Optionv(cli.CMD_ENV, kit.Simple( "ctx_dev", m.Conf(cli.RUNTIME, "conf.ctx_dev"), - "ctx_log", "boot.log", "ctx_mod", "ctx,log,gdb,ssh", "PATH", kit.Path(path.Join(p, "bin"))+":"+os.Getenv("PATH"), - ) - m.Cmd(m.Confv(DREAM, "meta.cmd"), "self", name) + "USER", cli.UserName, + m.Confv(DREAM, "meta.env"), + )) + m.Cmd(cli.DAEMON, m.Confv(DREAM, "meta.cmd"), "self", name) } m.Cmdy(nfs.DIR, p) } const DREAM = "dream" +const ( + DREAM_START = "dream.start" + DREAM_STOP = "dream.stop" +) func init() { Index.Merge(&ice.Context{ Configs: map[string]*ice.Config{ DREAM: {Name: "dream", Help: "梦想家", Value: kit.Data("path", "usr/local/work", - // "cmd", []interface{}{cli.SYSTEM, "ice.sh", "start", ice.WEB_SPACE, "connect"}, - "cmd", []interface{}{cli.SYSTEM, "ice.bin", SPACE, "connect"}, + "cmd", []interface{}{"ice.bin", SPACE, "connect"}, "env", kit.Dict( + "ctx_log", "bin/boot.log", "ctx_mod", "ctx,log,gdb,ssh", + ), + "miss", `#!/bin/bash +git &>/dev/null || yum install -y git + +[ -f ~/.ish/plug.sh ] || [ -f ./.ish/plug.sh ] || git clone https://github.com/shylinux/intshell ./.ish +[ "$ISH_CONF_PRE" != "" ] || source ./.ish/plug.sh || source ~/.ish/plug.sh +# declare -f ish_help_repos &>/dev/null || require conf.sh + +require show.sh +require help.sh +require miss.sh + +ish_miss_prepare_volcanos +# ish_miss_prepare_icebergs +# ish_miss_prepare toolkits +# ish_miss_prepare_intshell +# ish_miss_prepare learning + +go &>/dev/null || yum install -y golang +ish_miss_prepare_compile +ish_miss_prepare_install +make || yum install -y make + +`, )}, }, Commands: map[string]*ice.Command{ - DREAM: {Name: "dream [name] auto", Help: "梦想家", Meta: kit.Dict("detail", []interface{}{"启动", "停止"}), Action: map[string]*ice.Action{ - "start": {Name: "start", Help: "启动", Hand: func(m *ice.Message, arg ...string) { + DREAM: {Name: "dream [name [cmd...]] auto", Help: "梦想家", Meta: kit.Dict("detail", []interface{}{"启动", "停止"}), Action: map[string]*ice.Action{ + gdb.START: {Name: "start", Help: "启动", Hand: func(m *ice.Message, arg ...string) { _dream_show(m, m.Option(kit.MDB_NAME)) }}, - "stop": {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) { - m.Cmd(SPACE, m.Option("name"), "exit", "1") + gdb.STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) { + m.Cmd(SPACE, m.Option(kit.MDB_NAME), "exit", "1") + }}, + gdb.RESTART: {Name: "restart", Help: "重启", Hand: func(m *ice.Message, arg ...string) { + m.Cmd(SPACE, m.Option(kit.MDB_NAME), "exit", "1") + m.Sleep("1s") + _dream_show(m, m.Option(kit.MDB_NAME)) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { _dream_list(m) return } + if len(arg) > 1 { + m.Cmdy(SPACE, arg[0], arg[1:]) + return + } _dream_show(m, arg[0]) }}, }, diff --git a/base/web/space.go b/base/web/space.go index d266d659..9970e90f 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -236,10 +236,16 @@ func init() { task.Put(name, func(task *task.Task) error { // 监听消息 - m.Event(gdb.SPACE_START, WORKER, name) + switch kind { + case WORKER: + m.Event(DREAM_START, name) + defer m.Event(DREAM_STOP, name) + default: + m.Event(gdb.SPACE_START, kind, name) + defer m.Event(gdb.SPACE_CLOSE, kind, name) + } _space_handle(m, false, m.Target().Server().(*Frame).send, s, name) m.Log(ice.LOG_CLOSE, "%s: %s", name, kit.Format(m.Confv(SPACE, kit.Keys(kit.MDB_HASH, h)))) - m.Event(gdb.SPACE_CLOSE, WORKER, name) m.Confv(SPACE, kit.Keys(kit.MDB_HASH, h), "") return nil }) diff --git a/logs.go b/logs.go index 29433df1..0d484241 100644 --- a/logs.go +++ b/logs.go @@ -8,6 +8,9 @@ import ( "strings" ) +var ErrWarn = "warn: " +var ErrNotFound = "not found " + func (m *Message) log(level string, str string, arg ...interface{}) *Message { if str = strings.TrimSpace(fmt.Sprintf(str, arg...)); Log != nil { // 日志模块 @@ -33,7 +36,8 @@ func (m *Message) log(level string, str string, arg ...interface{}) *Message { // 文件行号 switch level { - case LOG_CMDS, LOG_INFO, LOG_WARN, "refer", "form": + // case LOG_CMDS, LOG_INFO, LOG_WARN, "refer", "form": + case LOG_CMDS, LOG_INFO, "refer", "form": case "register", "begin": default: suffix += " " + kit.FileLine(3, 2) @@ -60,7 +64,7 @@ func (m *Message) Info(str string, arg ...interface{}) *Message { } func (m *Message) Warn(err bool, arg ...interface{}) bool { if err { - m.meta[MSG_RESULT] = append([]string{"warn: "}, kit.Simple(arg...)...) + m.meta[MSG_RESULT] = append([]string{ErrWarn}, kit.Simple(arg...)...) return m.log(LOG_WARN, fmt.Sprint(arg...)) != nil } return false diff --git a/meta.go b/meta.go index b9b07675..ad61fed3 100644 --- a/meta.go +++ b/meta.go @@ -357,11 +357,15 @@ func (m *Message) Parse(meta string, key string, arg ...string) *Message { } func (m *Message) Split(str string, field string, space string, enter string) *Message { indexs := []int{} - fields := kit.Split(field, space, "{}") - for i, l := range kit.Split(str, enter, "{}") { + fields := kit.Split(field, space, space, space) + for i, l := range kit.Split(str, enter, enter, enter) { + m.Debug("----%v----", l) + if strings.TrimSpace(l) == "" { + continue + } if i == 0 && (field == "" || field == "index") { // 表头行 - fields = kit.Split(l, space) + fields = kit.Split(l, space, space) if field == "index" { for _, v := range fields { indexs = append(indexs, strings.Index(l, v)) @@ -382,7 +386,7 @@ func (m *Message) Split(str string, field string, space string, enter string) *M continue } - for i, v := range kit.Split(l, space) { + for i, v := range kit.Split(l, space, space) { m.Push(kit.Select("some", fields, i), v) } } diff --git a/misc.go b/misc.go index 9f0eb50e..4b467837 100644 --- a/misc.go +++ b/misc.go @@ -28,6 +28,9 @@ func (m *Message) Load(arg ...string) *Message { } func (m *Message) Watch(key string, arg ...string) *Message { + if len(arg) == 0 { + arg = append(arg, m.Prefix("auto")) + } m.Cmd("gdb.event", "listen", key, arg) return m } diff --git a/misc/docker/docker.go b/misc/docker/docker.go index 8d6137e8..e7fa24aa 100644 --- a/misc/docker/docker.go +++ b/misc/docker/docker.go @@ -5,10 +5,13 @@ import ( "github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/gdb" "github.com/shylinux/icebergs/base/mdb" + "github.com/shylinux/icebergs/base/nfs" "github.com/shylinux/icebergs/base/web" "github.com/shylinux/icebergs/core/code" kit "github.com/shylinux/toolkits" + "os" + "path" "strings" ) @@ -16,85 +19,101 @@ const DOCKER = "docker" const ( IMAGE = "image" CONTAINER = "container" + COMMAND = "command" ) +var _docker = []string{cli.SYSTEM, DOCKER} +var _image = []string{cli.SYSTEM, DOCKER, IMAGE} +var _container = []string{cli.SYSTEM, DOCKER, CONTAINER} + var Index = &ice.Context{Name: "docker", Help: "虚拟机", - Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ DOCKER: {Name: "docker", Help: "虚拟机", Value: kit.Data( - kit.MDB_SHORT, "name", "build", []interface{}{}), - }, + "repos", "centos", "build", []interface{}{"home", "mount"}, + )}, }, Commands: map[string]*ice.Command{ - IMAGE: {Name: "image", Help: "镜像管理", Meta: kit.Dict("detail", []string{"运行", "清理", "删除"}), List: ListLook("IMAGE_ID"), Action: map[string]*ice.Action{ + IMAGE: {Name: "image IMAGE_ID=auto auto", Help: "镜像管理", Meta: kit.Dict( + "detail", []string{"运行", "清理", "删除"}, + ), Action: map[string]*ice.Action{ "run": {Name: "run", Help: "运行", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(cli.SYSTEM, DOCKER, "run", "-dt", m.Option("REPOSITORY")+":"+m.Option("TAG")) + m.Cmdy(_docker, "run", "-dt", m.Option("REPOSITORY")+":"+m.Option("TAG")) }}, - "prune": {Name: "prune", Help: "清理", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(cli.SYSTEM, DOCKER, "prune", "-f") + gdb.PRUNE: {Name: "prune", Help: "清理", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(_image, "prune", "-f") }}, - mdb.DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(cli.SYSTEM, DOCKER, "rm", m.Option("IMAGE_ID")) + gdb.CLEAR: {Name: "clear", Help: "删除", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(_image, "rm", m.Option("IMAGE_ID")) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := []string{cli.SYSTEM, DOCKER, IMAGE} if len(arg) > 0 { // 容器详情 - res := m.Cmdx(prefix, "inspect", arg[0]) + res := m.Cmdx(_image, "inspect", arg[0]) m.Push("detail", kit.KeyValue(map[string]interface{}{}, "", kit.Parse(nil, "", kit.Split(res)...))) return } // 镜像列表 - m.Split(strings.Replace(m.Cmdx(prefix, "ls"), "IMAGE ID", "IMAGE_ID", 1), "index", " ", "\n") + m.Split(strings.Replace(m.Cmdx(_image, "ls"), "IMAGE ID", "IMAGE_ID", 1), "index", " ", "\n") m.Sort("REPOSITORY") }}, - CONTAINER: {Name: "container", Help: "容器管理", List: ListLook("CONTAINER_ID"), Meta: kit.Dict("detail", []string{"进入", "启动", "停止", "重启", "清理", "编辑", "删除"}), Action: map[string]*ice.Action{ - "prune": {Name: "prune", Help: "清理", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(cli.SYSTEM, DOCKER, "prune", "-f") - m.Cmdy(prefix, "prune", "-f") + CONTAINER: {Name: "container CONTAINER_ID=auto auto", Help: "容器管理", Meta: kit.Dict( + "detail", []string{"进入", "启动", "停止", "重启", "清理", "编辑", "删除"}, + ), Action: map[string]*ice.Action{ + gdb.OPEN: {Name: "open", Help: "进入", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(cli.SYSTEM, "tmux", "new-window", "-t", m.Option("NAMES"), "-n", m.Option("NAMES"), + "-PF", "#{session_name}:#{window_name}.1", "docker exec -it "+m.Option("NAMES")+" bash") + }}, + gdb.START: {Name: "start", Help: "启动", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(_container, "start", m.Option("CONTAINER_ID")) + }}, + gdb.STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(_container, "stop", m.Option("CONTAINER_ID")) + }}, + gdb.RESTART: {Name: "restart", Help: "重启", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(_container, "restart", m.Option("CONTAINER_ID")) + }}, + gdb.CHANGE: {Name: "change", Help: "更改", Hand: func(m *ice.Message, arg ...string) { + switch arg[0] { + case "NAMES": + m.Cmdy(_container, "rename", m.Option("CONTAINER_ID"), arg[1]) + } + }}, + gdb.PRUNE: {Name: "prune", Help: "清理", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(_container, "prune", "-f") + }}, + gdb.CLEAR: {Name: "clear", Help: "删除", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(_container, "rm", m.Option("CONTAINER_ID")) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := []string{cli.SYSTEM, DOCKER, CONTAINER} - if len(arg) > 1 && arg[0] == "action" { - switch arg[1] { - case "进入": - m.Cmdy(cli.SYSTEM, "tmux", "new-window", "-t", m.Option("NAMES"), "-n", m.Option("NAMES"), - "-PF", "#{session_name}:#{window_name}.1", "docker exec -it "+m.Option("NAMES")+" bash").Set("append") - return - case "停止": - m.Cmdy(prefix, "stop", m.Option("CONTAINER_ID")) - case "启动": - m.Cmdy(prefix, "start", m.Option("CONTAINER_ID")) - case "重启": - m.Cmdy(prefix, "restart", m.Option("CONTAINER_ID")) - case "清理": - m.Cmdy(prefix, "prune", "-f") - case "modify": - switch arg[2] { - case "NAMES": - m.Cmdy(prefix, "rename", arg[4], arg[3]) - } - case "delete": - m.Cmdy(prefix, "rm", m.Option("CONTAINER_ID")).Set("append") - } - return - } - if len(arg) > 0 { // 容器详情 - res := m.Cmdx(prefix, "inspect", arg[0]) + res := m.Cmdx(_container, "inspect", arg[0]) m.Push("detail", kit.KeyValue(map[string]interface{}{}, "", kit.Parse(nil, "", kit.Split(res)...))) return } // 容器列表 - m.Split(strings.Replace(m.Cmdx(prefix, "ls", "-a"), "CONTAINER ID", "CONTAINER_ID", 1), "index", " ", "\n") + m.Split(strings.Replace(m.Cmdx(_container, "ls", "-a"), "CONTAINER ID", "CONTAINER_ID", 1), "index", " ", "\n") m.Sort("NAMES") + + m.Table(func(index int, value map[string]string, head []string) { + for _, k := range []string{"open", "start", "stop", "restart", "clear"} { + m.Push(k, m.Cmdx(mdb.RENDER, web.RENDER.Button, k)) + } + }) + }}, + COMMAND: {Name: "command NAMES=auto cmd... auto", Help: "命令管理", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) < 2 { + m.Cmdy(CONTAINER) + return + } + m.Echo(m.Cmdx(_container, "exec", arg[0], kit.Split(kit.Select("pwd", arg, 1), " ", " "))) }}, - "init": {Name: "init", Help: "初始化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Watch(gdb.DREAM_START, m.Prefix("auto")) + gdb.INIT: {Name: "init", Help: "初始化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Watch(web.DREAM_START) + return if m.Richs(web.FAVOR, nil, "alpine.auto", nil) == nil { m.Cmd(web.FAVOR, "alpine.auto", web.TYPE_SHELL, "镜像源", `sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories`) @@ -102,60 +121,46 @@ var Index = &ice.Context{Name: "docker", Help: "虚拟机", m.Cmd(web.FAVOR, "alpine.auto", web.TYPE_SHELL, "软件包", `apk add curl`) } }}, - "auto": {Name: "auto", Help: "自动化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := []string{cli.SYSTEM, "docker"} - - if m.Cmd(prefix, "container", "start", arg[0]).Append("code") != "1" { - // 启动容器 - return - } - - args := []string{} - kit.Fetch(m.Confv("docker", "meta.build"), func(index int, value string) { - switch value { - case "home": - args = append(args, "-w", "/root") - case "mount": - args = append(args, "--mount", kit.Format("type=bind,source=%s,target=/root", kit.Path(m.Conf(web.DREAM, "meta.path"), arg[0]))) + gdb.AUTO: {Name: "auto", Help: "自动化", Action: map[string]*ice.Action{ + web.DREAM_START: {Name: "dream.start", Hand: func(m *ice.Message, arg ...string) { + if m.Cmd(_container, "start", arg[0]).Append(cli.CMD_CODE) == "0" { + // 启动容器 + return } - }) - // 创建容器 - pid := m.Cmdx(prefix, "run", "-dt", args, "--name", arg[0], "alpine") - m.Log(ice.LOG_CREATE, "%s: %s", arg[0], pid) + args := []string{"--name", arg[0]} + kit.Fetch(m.Confv(DOCKER, "meta.build"), func(index int, value string) { + switch value { + case "home": + args = append(args, "-w", "/root") + case "mount": + p := kit.Path(m.Conf(web.DREAM, "meta.path"), arg[0]) + args = append(args, "--mount", kit.Format("type=bind,source=%s,target=/root", p)) - m.Cmd(web.FAVOR, kit.Select("alpine.auto", arg, 1)).Table(func(index int, value map[string]string, head []string) { - if value["type"] == web.TYPE_SHELL { - // 执行命令 - m.Cmd(prefix, "exec", arg[0], kit.Split(value["text"])) - } - }) - }}, + p = path.Join(p, ".bashrc") + if _, e := os.Stat(p); e != nil { + m.Cmd(nfs.SAVE, p, kit.Format("export ctx_dev=%s\nexport ctx_pod=%s\n", + m.Conf(cli.RUNTIME, "conf.ctx_dev"), arg[0])) + } - "command": {Name: "command", Help: "命令", List: kit.List( - kit.MDB_INPUT, "text", "name", "CONTAINER_ID", - kit.MDB_INPUT, "text", "name", "cmd", "className", "args cmd", - kit.MDB_INPUT, "button", "value", "执行", - ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) < 2 { - m.Cmdy("container") + } + }) + + // 创建容器 + repos := m.Conf(DOCKER, "meta.repos") + pid := m.Cmdx(_docker, "run", "-dt", args, repos) + m.Log_CREATE(repos, arg[0], "pid", pid) return - } - prefix := []string{cli.SYSTEM, "docker", "container"} - m.Cmdy(prefix, "exec", arg[0], arg[1:]).Set("append") - }}, + + m.Cmd(web.FAVOR, kit.Select(repos+".auto", arg, 1)).Table(func(index int, value map[string]string, head []string) { + if value[kit.MDB_TYPE] == web.TYPE_SHELL { + m.Cmd(_container, "exec", arg[0], kit.Split(value[kit.MDB_TEXT])) + // 执行命令 + } + }) + }}, + }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, }, } func init() { code.Index.Register(Index, nil) } - -func ListLook(name ...string) []interface{} { - list := []interface{}{} - for _, k := range name { - list = append(list, kit.MDB_INPUT, "text", "name", k, "action", "auto") - } - return kit.List(append(list, - kit.MDB_INPUT, "button", "name", "查看", "action", "auto", - kit.MDB_INPUT, "button", "name", "返回", "cb", "Last", - )...) -} diff --git a/misc/tmux/tmux.go b/misc/tmux/tmux.go index 8892dc0c..ccf1be37 100644 --- a/misc/tmux/tmux.go +++ b/misc/tmux/tmux.go @@ -4,6 +4,7 @@ import ( ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/gdb" + "github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/web" "github.com/shylinux/icebergs/core/code" kit "github.com/shylinux/toolkits" @@ -14,28 +15,39 @@ import ( "time" ) +const TMUX = "tmux" +const ( + TEXT = "text" + BUFFER = "buffer" + SESSION = "session" + WINDOW = "window" + PANE = "pane" + VIEW = "view" + + LOCAL = "local" + RELAY = "relay" +) + +var _tmux = []string{cli.SYSTEM, TMUX} + var Index = &ice.Context{Name: "tmux", Help: "工作台", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ - "prefix": {Name: "prefix", Help: "前缀", Value: kit.Data("cmd", []interface{}{cli.SYSTEM, "tmux"})}, - "buffer": {Name: "buffer", Help: "缓存", Value: kit.Data()}, - - "session": {Name: "session", Help: "会话", Value: kit.Data( + SESSION: {Name: "session", Help: "会话", Value: kit.Data( "format", "#{session_id},#{session_attached},#{session_name},#{session_windows},#{session_height},#{session_width}", "fields", "id,tag,session,windows,height,width", )}, - "windows": {Name: "window", Help: "窗口", Value: kit.Data( + WINDOW: {Name: "windows", Help: "窗口", Value: kit.Data( "format", "#{window_id},#{window_active},#{window_name},#{window_panes},#{window_height},#{window_width}", "fields", "id,tag,window,panes,height,width", )}, - "panes": {Name: "pane", Help: "终端", Value: kit.Data( + PANE: {Name: "panes", Help: "终端", Value: kit.Data( "format", "#{pane_id},#{pane_active},#{pane_index},#{pane_tty},#{pane_height},#{pane_width}", "fields", "id,tag,pane,tty,height,width", )}, - "view": {Name: "pane", Help: "终端", Value: kit.Data()}, - "local": {Name: "local", Help: "虚拟机", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME)}, - "relay": {Name: "relay", Help: "跳板机", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME, + LOCAL: {Name: "local", Help: "虚拟机", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME)}, + RELAY: {Name: "relay", Help: "跳板机", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME, "count", 100, "sleep", "100ms", "tail", kit.Dict( "verify", "Verification code:", "password", "Password:", @@ -44,6 +56,151 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", )}, }, Commands: map[string]*ice.Command{ + TEXT: {Name: "text 保存:button text:textarea", Help: "文本", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) > 0 && arg[0] != "" { + m.Cmd(_tmux, "set-buffer", arg[0]) + } + m.Echo(m.Cmdx(_tmux, "show-buffer")) + }}, + BUFFER: {Name: "buffer [buffer=auto [value]] auto", Help: "缓存", Action: map[string]*ice.Action{ + mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { + switch arg[0] { + case "text": + m.Cmd(_tmux, "set-buffer", "-b", m.Option("buffer"), arg[1]) + } + }}, + }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) > 1 { + // 设置缓存 + m.Cmd(_tmux, "set-buffer", "-b", arg[0], arg[1]) + } + if len(arg) > 0 { + // 查看缓存 + m.Echo(m.Cmdx(_tmux, "show-buffer", "-b", arg[0])) + return + } + + // 缓存列表 + for i, v := range kit.Split(m.Cmdx(_tmux, "list-buffers"), "\n", "\n", "\n") { + ls := strings.SplitN(v, ": ", 3) + m.Push("buffer", ls[0]) + m.Push("size", ls[1]) + if i < 3 { + m.Push("text", m.Cmdx(_tmux, "show-buffer", "-b", ls[0])) + } else { + m.Push("text", ls[2][1:]) + } + } + }}, + SESSION: {Name: "session [session=auto [window=auto [pane=auto [cmd]]]] auto", Help: "会话管理", Meta: kit.Dict( + "detail", []string{"选择", "编辑", "删除"}, + ), Action: map[string]*ice.Action{ + "choice": {Name: "choice", Help: "选择", Hand: func(m *ice.Message, arg ...string) { + m.Cmd(_tmux, "switch-client", "-t", m.Option(SESSION)) + if m.Option(WINDOW) != "" { + m.Cmd(_tmux, "select-window", "-t", m.Option(SESSION)+":"+m.Option(WINDOW)) + } + if m.Option(PANE) != "" { + m.Cmd(_tmux, "select-pane", "-t", m.Option(SESSION)+":"+m.Option(WINDOW)+"."+m.Option(PANE)) + } + }}, + mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { + switch arg[0] { + case SESSION: + // 重命名会话 + m.Cmd(_tmux, "rename-session", "-t", m.Option(SESSION), arg[1]) + case WINDOW: + // 重命名窗口 + m.Cmd(_tmux, "rename-window", "-t", m.Option(SESSION)+":"+m.Option(WINDOW), arg[1]) + } + }}, + gdb.CLEAR: {Name: "clear", Help: "删除", Hand: func(m *ice.Message, arg ...string) { + if m.Option(PANE) != "" { + m.Cmd(_tmux, "kill-pane", "-t", m.Option(SESSION)+":"+m.Option(WINDOW)+"."+m.Option(PANE)) + return + } + if m.Option(WINDOW) != "" { + m.Cmd(_tmux, "kill-window", "-t", m.Option(SESSION)+":"+m.Option(WINDOW)) + return + } + if m.Option(SESSION) != "" { + m.Cmd(_tmux, "kill-session", "-t", m.Option(SESSION)) + return + } + }}, + }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + target := "" + if len(arg) > 3 { + // 执行命令 + target = arg[0] + ":" + arg[1] + "." + arg[2] + m.Cmd(_tmux, "send-keys", "-t", target, strings.Join(arg[3:], " "), "Enter") + time.Sleep(1 * time.Second) + } + if len(arg) > 2 { + // 终端内容 + m.Echo(strings.TrimSpace(m.Cmdx(VIEW, target))) + return + } + + if len(arg) == 0 { + // 会话列表 + m.Split(m.Cmdx(_tmux, "list-session", "-F", m.Conf(cmd, "meta.format")), m.Conf(cmd, "meta.fields"), ",", "\n") + + m.Table(func(index int, value map[string]string, head []string) { + for _, k := range []string{"clear"} { + m.Push(k, m.Cmdx(mdb.RENDER, web.RENDER.Button, k)) + } + }) + return + } + + target = arg[0] + if m.Cmd(_tmux, "has-session", "-t", target).Append(cli.CMD_CODE) != "0" { + // 创建会话 + m.Option(cli.CMD_ENV, "TMUX", "") + m.Option(cli.CMD_DIR, m.Conf(web.DREAM, "meta.path")) + m.Cmd(_tmux, "new-session", "-ds", arg[0]) + // m.Cmd("auto", arg[0]) + } + if len(arg) == 1 { + // 窗口列表 + m.Cmdy(WINDOW, target) + return + } + + switch arg[1] { + case "has": + m.Cmd(WINDOW, target).Table(func(index int, value map[string]string, head []string) { + if value["window"] == arg[2] { + m.Echo("true") + } + }) + return + } + + if target = arg[0] + ":" + arg[1]; m.Cmd(_tmux, "rename-window", "-t", target, arg[1]).Append(cli.CMD_CODE) != "0" { + // 创建窗口 + m.Cmd(_tmux, "switch-client", "-t", arg[0]) + m.Cmd(_tmux, "new-window", "-t", arg[0], "-dn", arg[1]) + } + if len(arg) == 2 { + // 终端列表 + m.Cmdy(PANE, target) + return + } + }}, + WINDOW: {Name: "windows", Help: "窗口", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Split(m.Cmdx(_tmux, "list-windows", "-t", kit.Select("", arg, 0), + "-F", m.Conf(cmd, "meta.format")), m.Conf(cmd, "meta.fields"), ",", "\n") + }}, + PANE: {Name: "panes", Help: "终端", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Split(m.Cmdx(_tmux, "list-panes", "-t", kit.Select("", arg, 0), + "-F", m.Conf(cmd, "meta.format")), m.Conf(cmd, "meta.fields"), ",", "\n") + }}, + VIEW: {Name: "view", Help: "终端", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Cmdy(_tmux, "capture-pane", "-pt", kit.Select("", arg, 0)).Set(ice.MSG_APPEND) + }}, + ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if m.Cmdy(cli.SYSTEM, "tmux", "ls"); m.Append("code") != "0" { return @@ -67,8 +224,9 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", code.PROJECT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }}, - "init": {Name: "init", Help: "初始化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Watch(gdb.DREAM_START, m.Prefix("auto")) + gdb.INIT: {Name: "init", Help: "初始化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Watch(gdb.DREAM_START) + return if m.Richs(web.FAVOR, nil, "tmux.auto", nil) == nil { m.Cmd(web.FAVOR, "tmux.auto", web.TYPE_SHELL, "脚本", `curl $ctx_dev/publish/auto.sh > auto.sh`) @@ -86,64 +244,73 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", } } }}, - "auto": {Name: "auto dream", Help: "自动化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := kit.Simple(m.Confv("prefix", "meta.cmd")) - - // 共享空间 - share, dev := "", kit.Select(m.Conf(cli.RUNTIME, "conf.ctx_dev"), m.Conf(cli.RUNTIME, "host.ctx_self")) - m.Richs(web.SPACE, nil, arg[0], func(key string, value map[string]interface{}) { - share = kit.Format(value["share"]) - }) - - // 环境变量 - m.Option("cmd_env", "TMUX", "", "ctx_dev", dev, "ctx_share", share) - m.Option("cmd_dir", path.Join(m.Conf(web.DREAM, "meta.path"), arg[0])) - - if arg[0] != "" && m.Cmd(prefix, "has-session", "-t", arg[0]).Append("code") != "0" { - // 创建会话 - m.Cmd(prefix, "new-session", "-ds", arg[0]) - } - - if m.Option("local") != "" { - // 创建容器 - m.Cmd("local", m.Option("local"), arg[0]) - } - if m.Option("relay") != "" { - // 远程登录 - m.Cmd("relay", m.Option("relay"), arg[0]) - } - - for _, v := range kit.Simple(m.Optionv("before")) { - // 前置命令 - m.Cmdy(prefix, "send-keys", "-t", arg[0], v, "Enter") - } - - // 连接参数 - m.Cmdy(prefix, "send-keys", "-t", arg[0], "export ctx_dev=", dev, "Enter") - m.Cmdy(prefix, "send-keys", "-t", arg[0], "export ctx_share=", share, "Enter") - - m.Cmd(web.FAVOR, kit.Select("tmux.auto", arg, 1)).Table(func(index int, value map[string]string, head []string) { - switch value["type"] { - case web.TYPE_SHELL: - // 发送命令 - m.Cmdy(prefix, "send-keys", "-t", arg[0], value["text"], "Enter") - time.Sleep(10 * time.Millisecond) + gdb.AUTO: {Name: "auto", Help: "自动化", Action: map[string]*ice.Action{ + web.DREAM_START: {Name: "dream.start", Hand: func(m *ice.Message, arg ...string) { + if m.Cmd(_tmux, "has-session", "-t", arg[0]).Append(cli.CMD_CODE) == "0" { + return } - }) + // 创建会话 + m.Option(cli.CMD_ENV, "TMUX", "", "ctx_pod", arg[0], "ctx_dev", m.Conf(cli.RUNTIME, "conf.ctx_dev")) + m.Option(cli.CMD_DIR, path.Join(m.Conf(web.DREAM, "meta.path"), arg[0])) + m.Cmd(_tmux, "new-session", "-ds", arg[0]) + return + + // 共享空间 + share, dev := "", kit.Select(m.Conf(cli.RUNTIME, "conf.ctx_dev"), m.Conf(cli.RUNTIME, "host.ctx_self")) + m.Richs(web.SPACE, nil, arg[0], func(key string, value map[string]interface{}) { + share = kit.Format(value["share"]) + }) + + // 环境变量 + m.Option("cmd_env", "TMUX", "", "ctx_dev", dev, "ctx_share", share) + m.Option("cmd_dir", path.Join(m.Conf(web.DREAM, "meta.path"), arg[0])) + + if arg[0] != "" && m.Cmd(_tmux, "has-session", "-t", arg[0]).Append("code") != "0" { + // 创建会话 + m.Cmd(_tmux, "new-session", "-ds", arg[0]) + } + + if m.Option("local") != "" { + // 创建容器 + m.Cmd("local", m.Option("local"), arg[0]) + } + if m.Option("relay") != "" { + // 远程登录 + m.Cmd("relay", m.Option("relay"), arg[0]) + } + + for _, v := range kit.Simple(m.Optionv("before")) { + // 前置命令 + m.Cmdy(_tmux, "send-keys", "-t", arg[0], v, "Enter") + } + + // 连接参数 + m.Cmdy(_tmux, "send-keys", "-t", arg[0], "export ctx_dev=", dev, "Enter") + m.Cmdy(_tmux, "send-keys", "-t", arg[0], "export ctx_share=", share, "Enter") + + m.Cmd(web.FAVOR, kit.Select("tmux.auto", arg, 1)).Table(func(index int, value map[string]string, head []string) { + switch value["type"] { + case web.TYPE_SHELL: + // 发送命令 + m.Cmdy(_tmux, "send-keys", "-t", arg[0], value["text"], "Enter") + time.Sleep(10 * time.Millisecond) + } + }) + + for _, v := range kit.Simple(m.Optionv("after")) { + // 后置命令 + m.Cmdy(_tmux, "send-keys", "-t", arg[0], v, "Enter") + } + }}, + }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, - for _, v := range kit.Simple(m.Optionv("after")) { - // 后置命令 - m.Cmdy(prefix, "send-keys", "-t", arg[0], v, "Enter") - } - }}, "make": {Name: "make name cmd...", Help: "个性化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := kit.Simple(m.Confv("prefix", "meta.cmd")) session := m.Conf(cli.RUNTIME, "node.name") if arg[1] == "session" { session, arg[2], arg = arg[2], arg[0], arg[2:] } - if m.Warn(m.Cmd(prefix, "has-session", "-t", session).Append("code") != "0", "session miss") { + if m.Warn(m.Cmd(_tmux, "has-session", "-t", session).Append("code") != "0", "session miss") { // 会话不存在 return } @@ -155,183 +322,34 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", switch arg[1] { case "init": - m.Cmdx(prefix, "rename-window", "-t", session, arg[0]) + m.Cmdx(_tmux, "rename-window", "-t", session, arg[0]) arg[1], arg = arg[0], arg[1:] case "link": - m.Cmdx(prefix, "link-window", "-dt", session, "-s", arg[2]) + m.Cmdx(_tmux, "link-window", "-dt", session, "-s", arg[2]) return default: - m.Cmd(prefix, "new-window", "-dt", session, "-n", arg[0]) + m.Cmd(_tmux, "new-window", "-dt", session, "-n", arg[0]) } for _, v := range arg[1:] { switch ls := kit.Split(v); ls[1] { case "v": - m.Cmd(prefix, "split-window", "-h", "-dt", session+":"+arg[0]+"."+ls[0], ls[2:]) + m.Cmd(_tmux, "split-window", "-h", "-dt", session+":"+arg[0]+"."+ls[0], ls[2:]) case "u", "split-window": - m.Cmd(prefix, "split-window", "-dt", session+":"+arg[0]+"."+ls[0], ls[2:]) + m.Cmd(_tmux, "split-window", "-dt", session+":"+arg[0]+"."+ls[0], ls[2:]) case "k": - m.Cmd(prefix, "send-key", "-t", session+":"+arg[0]+"."+ls[0], ls[2:]) + m.Cmd(_tmux, "send-key", "-t", session+":"+arg[0]+"."+ls[0], ls[2:]) default: - m.Cmd(prefix, ls[1], "-t", session+":"+arg[0]+"."+ls[0], ls[2:]) + m.Cmd(_tmux, ls[1], "-t", session+":"+arg[0]+"."+ls[0], ls[2:]) } } }}, - "text": {Name: "text name 保存:button text:textarea", Help: "文本", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := kit.Simple(m.Confv("prefix", "meta.cmd")) - if len(arg) > 1 && arg[1] != "" { - m.Cmd(prefix, "set-buffer", arg[1]) - } - m.Cmdy(prefix, "show-buffer").Set(ice.MSG_APPEND) - }}, - "buffer": {Name: "buffer [buffer=auto [value]] auto", Help: "缓存", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := kit.Simple(m.Confv("prefix", "meta.cmd")) - if len(arg) > 1 { - // 设置缓存 - m.Cmd(prefix, "set-buffer", "-b", arg[0], arg[1]) - } - - if len(arg) > 0 { - // 查看缓存 - m.Cmdy(prefix, "show-buffer", "-b", arg[0]).Set(ice.MSG_APPEND) - return - } - - // 缓存列表 - for i, v := range kit.Split(m.Cmdx(prefix, "list-buffers"), "\n", "\n", "\n") { - ls := strings.SplitN(v, ": ", 3) - m.Push("buffer", ls[0]) - m.Push("size", ls[1]) - if i < 3 { - m.Push("text", m.Cmdx(prefix, "show-buffer", "-b", ls[0])) - } else { - m.Push("text", ls[2][1:]) - } - } - }}, - "session": {Name: "session [session=auto [window=auto [pane=auto [cmd]]]] auto", Help: "会话", Meta: kit.Dict( - "detail", []string{"选择", "编辑", "删除", "下载"}, - ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := kit.Simple(m.Confv("prefix", "meta.cmd")) - - if len(arg) > 1 && arg[0] == "action" { - switch arg[1] { - case "select", "选择": - if arg[2] == "session" { - // 选择会话 - m.Cmd(prefix, "switch-client", "-t", arg[3]) - break - } - - if m.Cmd(prefix, "switch-client", "-t", m.Option("session")); arg[2] == "window" { - // 选择窗口 - m.Cmd(prefix, "select-window", "-t", m.Option("session")+":"+arg[3]) - break - } - - if m.Cmd(prefix, "select-window", "-t", m.Option("session")+":"+m.Option("window")); arg[2] == "pane" { - // 选择终端 - m.Cmd(prefix, "select-pane", "-t", m.Option("session")+":"+m.Option("window")+"."+arg[3]) - } - case "modify", "编辑": - switch arg[2] { - case "session": - // 重命名会话 - m.Cmd(prefix, "rename-session", "-t", arg[4], arg[3]) - case "window": - // 重命名窗口 - m.Cmd(prefix, "rename-window", "-t", m.Option("session")+":"+arg[4], arg[3]) - } - case "delete", "删除": - switch arg[2] { - case "session": - // 删除会话 - m.Cmd(prefix, "kill-session", "-t", arg[3]) - case "window": - // 删除窗口 - m.Cmd(prefix, "kill-window", "-t", m.Option("session")+":"+arg[3]) - case "pane": - // 删除终端 - m.Cmd(prefix, "kill-pane", "-t", m.Option("session")+":"+m.Option("window")+"."+arg[3]) - } - } - return - } - - if len(arg) == 0 { - // 会话列表 - m.Split(m.Cmdx(prefix, "list-session", "-F", m.Conf(cmd, "meta.format")), m.Conf(cmd, "meta.fields"), ",", "\n") - return - } - - target := arg[0] - if m.Cmd(prefix, "has-session", "-t", target).Append("code") != "0" { - // 创建会话 - m.Option("cmd_env", "TMUX", "") - m.Option("cmd_dir", m.Conf(web.DREAM, "meta.path")) - m.Cmd(prefix, "new-session", "-ds", arg[0]) - m.Cmd("auto", arg[0]) - } - - if len(arg) == 1 { - // 窗口列表 - m.Cmdy("windows", target) - return - } - switch arg[1] { - case "has": - m.Cmd("windows", target).Table(func(index int, value map[string]string, head []string) { - if value["window"] == arg[2] { - m.Echo("true") - } - }) - return - } - - if target = arg[0] + ":" + arg[1]; m.Cmd(prefix, "rename-window", "-t", target, arg[1]).Append("code") != "0" { - // 创建窗口 - m.Cmd(prefix, "switch-client", "-t", arg[0]) - m.Cmd(prefix, "new-window", "-t", arg[0], "-dn", arg[1]) - } - - if len(arg) == 2 { - // 终端列表 - m.Cmdy("panes", target) - return - } - - if target = arg[0] + ":" + arg[1] + "." + arg[2]; len(arg) > 3 { - // 执行命令 - m.Cmd(prefix, "send-keys", "-t", target, strings.Join(arg[3:], " "), "Enter") - time.Sleep(1 * time.Second) - } - - // 终端内容 - m.Echo(strings.TrimSpace(m.Cmdx("view", target))) - }}, - "windows": {Name: "window", Help: "窗口", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := kit.Simple(m.Confv("prefix", "meta.cmd")) - m.Split(m.Cmdx(prefix, "list-windows", "-t", kit.Select("", arg, 0), - "-F", m.Conf(cmd, "meta.format")), m.Conf(cmd, "meta.fields"), ",", "\n") - }}, - "panes": {Name: "pane", Help: "终端", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := kit.Simple(m.Confv("prefix", "meta.cmd")) - m.Split(m.Cmdx(prefix, "list-panes", "-t", kit.Select("", arg, 0), - "-F", m.Conf(cmd, "meta.format")), m.Conf(cmd, "meta.fields"), ",", "\n") - }}, - "view": {Name: "view", Help: "终端", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := kit.Simple(m.Confv("prefix", "meta.cmd")) - m.Cmdy(prefix, "capture-pane", "-pt", kit.Select("", arg, 0)).Set(ice.MSG_APPEND) - }}, - "local": {Name: "local name name", Help: "虚拟机", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := kit.Simple(m.Confv("prefix", "meta.cmd")) m.Cmd("web.code.docker.auto", arg[1]) - m.Cmdy(prefix, "send-keys", "-t", arg[1], "docker exec -it ", arg[1], " bash", "Enter") + m.Cmdy(_tmux, "send-keys", "-t", arg[1], "docker exec -it ", arg[1], " bash", "Enter") }}, "relay": {Name: "relay [name [favor]]", Help: "跳板机", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := kit.Simple(m.Confv("prefix", "meta.cmd")) if len(arg) == 0 { // 认证列表 m.Richs(cmd, nil, "*", func(key string, value map[string]interface{}) { @@ -357,22 +375,22 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", m.Richs(cmd, nil, arg[0], func(key string, value map[string]interface{}) { // 登录命令 - m.Cmdy(prefix, "send-keys", "-t", arg[1], kit.Format("ssh %s@%s", value["username"], value["website"]), "Enter") + m.Cmdy(_tmux, "send-keys", "-t", arg[1], kit.Format("ssh %s@%s", value["username"], value["website"]), "Enter") sleep := kit.Duration(m.Conf(cmd, "meta.sleep")) for i := 0; i < kit.Int(m.Conf(cmd, "meta.count")); i++ { time.Sleep(sleep) - list := strings.Split(strings.TrimSpace(m.Cmdx(prefix, "capture-pane", "-p")), "\n") + list := strings.Split(strings.TrimSpace(m.Cmdx(_tmux, "capture-pane", "-p")), "\n") if tail := list[len(list)-1]; tail == m.Conf(cmd, "meta.tail.login") { // 登录成功 break } else if tail == m.Conf(cmd, "meta.tail.password") { // 输入密码 - m.Cmdy(prefix, "send-keys", "-t", arg[1], value["password"], "Enter") + m.Cmdy(_tmux, "send-keys", "-t", arg[1], value["password"], "Enter") } else if tail == m.Conf(cmd, "meta.tail.verify") { // 输入密码 - m.Cmdy(prefix, "send-keys", "-t", arg[1], m.Cmdx("aaa.totp.get", value["text"]), "Enter") + m.Cmdy(_tmux, "send-keys", "-t", arg[1], m.Cmdx("aaa.totp.get", value["text"]), "Enter") } } }) diff --git a/type.go b/type.go index 4c0d2ffe..1eff6853 100644 --- a/type.go +++ b/type.go @@ -562,7 +562,7 @@ func (m *Message) Cmd(arg ...interface{}) *Message { }) }) - if m.Warn(m.Hand == false, "not found %v", list) { + if m.Warn(m.Hand == false, ErrNotFound, list) { return m.Set(MSG_RESULT).Cmd("cli.system", list) } return m