diff --git a/base/cli/daemon.go b/base/cli/daemon.go index bd3deb0c..da6c5a3a 100644 --- a/base/cli/daemon.go +++ b/base/cli/daemon.go @@ -73,7 +73,7 @@ func init() { }}, "prune": {Name: "prune", Help: "清理", Hand: func(m *ice.Message, arg ...string) { m.Richs(DAEMON, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { - if strings.Count(m.Cmdx(SYSTEM, "ps", value[kit.MDB_PID]), "\n") == 1 { + if value["status"] == "error" || strings.Count(m.Cmdx(SYSTEM, "ps", value[kit.MDB_PID]), "\n") == 1 { m.Conf(DAEMON, kit.Keys(kit.MDB_HASH, key), "") m.Log_DELETE(DAEMON, kit.Format(value)) } diff --git a/base/tcp/tcp.go b/base/tcp/tcp.go index c25d406a..01dd7233 100644 --- a/base/tcp/tcp.go +++ b/base/tcp/tcp.go @@ -27,7 +27,7 @@ func _port_get(m *ice.Message, begin string) string { for i := current; i < end; i++ { if m.Cmd(cli.SYSTEM, "lsof", "-i", kit.Format(":%d", i)).Append(cli.CMD_CODE) != "0" { m.Conf(PORT, "meta.current", i) - m.Log_CREATE(PORT, i) + m.Log_SELECT(PORT, i) return kit.Format("%d", i) } } @@ -116,7 +116,7 @@ var Index = &ice.Context{Name: "tcp", Help: "通信模块", }}, "select": {Name: "select [begin]", Help: "分配端口", Hand: func(m *ice.Message, arg ...string) { port, p := kit.Select("", arg, 0), "" - for { + for i := 0; i < 10; i++ { port = _port_get(m, port) p = path.Join(m.Conf(cli.DAEMON, kit.META_PATH), port) if _, e := os.Stat(p); e != nil && os.IsNotExist(e) { diff --git a/core/code/install.go b/core/code/install.go index ccb57cf9..3b10c134 100644 --- a/core/code/install.go +++ b/core/code/install.go @@ -19,20 +19,20 @@ const INSTALL = "install" func init() { Index.Merge(&ice.Context{ Configs: map[string]*ice.Config{ - INSTALL: {Name: "install", Help: "安装", Value: kit.Data( + INSTALL: {Name: INSTALL, Help: "安装", Value: kit.Data( kit.MDB_SHORT, kit.MDB_NAME, kit.MDB_PATH, "usr/install", )}, }, Commands: map[string]*ice.Command{ - INSTALL: {Name: "install name=auto auto", Help: "安装", Action: map[string]*ice.Action{ + INSTALL: {Name: "install name=auto port=auto path=auto auto", Help: "安装", Meta: kit.Dict(), Action: map[string]*ice.Action{ "download": {Name: "download link", Help: "下载", Hand: func(m *ice.Message, arg ...string) { name := path.Base(arg[0]) if m.Richs(INSTALL, "", name, func(key string, value map[string]interface{}) { - if _, e := os.Stat(path.Join(m.Conf(INSTALL, kit.META_PATH), kit.Format(value["name"]))); e == nil { - m.Push(key, value, []string{"time", "progress", "size", "name", "link"}) + if _, e := os.Stat(path.Join(m.Conf(INSTALL, kit.META_PATH), kit.Format(value[kit.MDB_NAME]))); e == nil { + m.Push(key, value, []string{kit.MDB_TIME, kit.MDB_STEP, kit.MDB_SIZE, kit.MDB_NAME, kit.MDB_LINK}) } - }) != nil && len(m.Appendv("name")) > 0 { - // 查询 + }) != nil && len(m.Appendv(kit.MDB_NAME)) > 0 { + // 已经下载 return } @@ -40,51 +40,95 @@ func init() { m.Cmd(mdb.INSERT, m.Prefix(INSTALL), "", mdb.HASH, kit.MDB_NAME, name, kit.MDB_LINK, arg[0]) m.Richs(INSTALL, "", name, func(key string, value map[string]interface{}) { m.Optionv("progress", func(size int, total int) { - p := size * 100 / total - if p != kit.Int(value["progress"]) && p%10 == 0 { - m.Log_IMPORT(kit.MDB_FILE, name, "per", size*100/total, kit.MDB_SIZE, kit.FmtSize(int64(size)), "total", kit.FmtSize(int64(total))) + s := size * 100 / total + if s != kit.Int(value[kit.MDB_STEP]) && s%10 == 0 { + m.Log_IMPORT(kit.MDB_FILE, name, kit.MDB_STEP, s, kit.MDB_SIZE, kit.FmtSize(int64(size)), kit.MDB_TOTAL, kit.FmtSize(int64(total))) } - value["progress"], value["size"], value["total"] = p, size, total + value[kit.MDB_STEP], value[kit.MDB_SIZE], value[kit.MDB_TOTAL] = s, size, total }) }) + // 占位 + p := path.Join(m.Conf(INSTALL, kit.META_PATH), name) + m.Cmd(cli.SYSTEM, "touch", p) + // 下载 m.Option(cli.CMD_DIR, m.Conf(INSTALL, kit.META_PATH)) if strings.HasPrefix(arg[0], "ftp") { m.Cmdy(cli.SYSTEM, "wget", arg[0]) } else { msg := m.Cmd(web.SPIDE, web.SPIDE_DEV, web.SPIDE_CACHE, web.SPIDE_GET, arg[0]) - p := path.Join(m.Conf(INSTALL, kit.META_PATH), name) - m.Cmdy(nfs.LINK, p, msg.Append("file")) + m.Cmdy(nfs.LINK, p, msg.Append(kit.MDB_FILE)) } // 解压 m.Cmd(cli.SYSTEM, "tar", "xvf", name) }}, - "start": {Name: "start source binary", Help: "启动", Hand: func(m *ice.Message, arg ...string) { - port := m.Cmdx(tcp.PORT, "get") - p := path.Join(m.Conf(cli.DAEMON, kit.META_PATH), port) - os.MkdirAll(p, ice.MOD_DIR) + "build": {Name: "build link", Help: "构建", Hand: func(m *ice.Message, arg ...string) { + p := m.Option(cli.CMD_DIR, path.Join(m.Conf(INSTALL, kit.META_PATH), kit.TrimExt(arg[0]))) + switch cb := m.Optionv("prepare").(type) { + case func(string): + cb(p) + default: + m.Cmdy(cli.SYSTEM, "./configure", "--prefix="+kit.Path(path.Join(p, INSTALL)), arg[1:]) + } - // 复制 - m.Cmd(nfs.DIR, path.Join(m.Conf(INSTALL, kit.META_PATH), arg[0])).Table(func(index int, value map[string]string, head []string) { - m.Cmd(cli.SYSTEM, "cp", "-r", strings.TrimSuffix(value[kit.MDB_PATH], "/"), p) + m.Cmdy(cli.SYSTEM, "make", "-j8") + m.Cmdy(cli.SYSTEM, "make", "PREFIX="+kit.Path(path.Join(p, INSTALL)), "install") + }}, + "spawn": {Name: "spawn link", Help: "新建", Hand: func(m *ice.Message, arg ...string) { + port := m.Cmdx(tcp.PORT, "select") + target := path.Join(m.Conf(cli.DAEMON, kit.META_PATH), port) + source := path.Join(m.Conf(INSTALL, kit.META_PATH), kit.TrimExt(arg[0])) + + m.Cmd(nfs.DIR, path.Join(source, INSTALL)).Table(func(index int, value map[string]string, head []string) { + m.Cmd(cli.SYSTEM, "cp", "-r", strings.TrimSuffix(value[kit.MDB_PATH], "/"), target) }) + m.Echo(target) + }}, + "start": {Name: "start link cmd...", Help: "启动", Hand: func(m *ice.Message, arg ...string) { + p := m.Option(cli.CMD_DIR, m.Cmdx(INSTALL, "spawn", arg[0])) - // 启动 - m.Option(cli.CMD_DIR, p) - m.Cmdy(cli.DAEMON, arg[1]) + args := []string{} + switch cb := m.Optionv("prepare").(type) { + case func(string) []string: + args = append(args, cb(p)...) + } + + m.Cmdy(cli.DAEMON, arg[1:], args) + }}, + "bench": {Name: "bench port cmd...", Help: "压测", Hand: func(m *ice.Message, arg ...string) { }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) > 0 { - // 详情 - m.Cmdy(mdb.SELECT, m.Prefix(INSTALL), "", mdb.HASH, kit.MDB_NAME, arg[0]) + if len(arg) == 0 { + // 源码列表 + m.Option(mdb.FIELDS, "time,step,size,total,name,link") + m.Cmdy(mdb.SELECT, m.Prefix(INSTALL), "", mdb.HASH) + m.Sort(kit.MDB_TIME, "time_r") return } - // 列表 - m.Option("fields", "time,progress,size,total,name,link") - m.Cmdy(mdb.SELECT, m.Prefix(INSTALL), "", mdb.HASH) + arg[0] = path.Base(arg[0]) + if key := strings.Split(strings.Split(arg[0], "-")[0], ".")[0]; len(arg) == 1 { + // 服务列表 + u := kit.ParseURL(m.Option(ice.MSG_USERWEB)) + m.Cmd(cli.DAEMON).Table(func(index int, value map[string]string, head []string) { + if strings.Contains(value[kit.MDB_NAME], key) { + m.Push(kit.MDB_TIME, value[kit.MDB_TIME]) + m.Push(kit.MDB_PORT, path.Base(value[kit.MDB_DIR])) + m.Push(kit.MDB_STATUS, value[kit.MDB_STATUS]) + m.Push(kit.MDB_NAME, value[kit.MDB_NAME]) + m.Push(kit.MDB_LINK, m.Cmdx(mdb.RENDER, web.RENDER.A, + kit.Format("http://%s:%s", u.Hostname(), path.Base(value[kit.MDB_DIR])))) + } + }) + m.Sort(kit.MDB_TIME, "time_r") + return + } + + // 目录列表 + m.Option(nfs.DIR_ROOT, path.Join(m.Conf(cli.DAEMON, kit.META_PATH), arg[1])) + m.Cmdy(nfs.DIR, kit.Select("./", arg, 2)) m.Sort(kit.MDB_TIME, "time_r") }}, }, diff --git a/misc/tmux/tmux.go b/misc/tmux/tmux.go index fda1a6a3..bdb764de 100644 --- a/misc/tmux/tmux.go +++ b/misc/tmux/tmux.go @@ -5,7 +5,6 @@ import ( "github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/gdb" "github.com/shylinux/icebergs/base/mdb" - "github.com/shylinux/icebergs/base/tcp" "github.com/shylinux/icebergs/base/web" "github.com/shylinux/icebergs/core/code" kit "github.com/shylinux/toolkits" @@ -61,57 +60,14 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台", Commands: map[string]*ice.Command{ TMUX: {Name: "tmux 启动:button 编译:button 下载:button", Help: "终端", Action: map[string]*ice.Action{ "download": {Name: "download", Help: "下载", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(code.INSTALL, "download", m.Conf(TMUX, "meta.source")) + m.Cmdy(code.INSTALL, "download", m.Conf(TMUX, kit.META_SOURCE)) }}, - "compile": {Name: "compile", Help: "编译", Hand: func(m *ice.Message, arg ...string) { - name := path.Base(strings.TrimSuffix(strings.TrimSuffix(m.Conf(TMUX, "meta.source"), ".tar.gz"), "zip")) - p := m.Option(cli.CMD_DIR, path.Join(m.Conf(code.INSTALL, kit.META_PATH), name)) - m.Cmdy(cli.SYSTEM, "./configure", "--prefix="+kit.Path(path.Join(p, "install"))) - m.Cmdy(cli.SYSTEM, "make", "-j8") - }}, - "start": {Name: "start", Help: "启动", Hand: func(m *ice.Message, arg ...string) { - // 分配 - port, p := "", "" - for { - port = m.Cmdx(tcp.PORT, "select", port) - p = path.Join(m.Conf(cli.DAEMON, kit.META_PATH), port) - if _, e := os.Stat(p); e != nil && os.IsNotExist(e) { - break - } - port = kit.Format(kit.Int(port) + 1) - } - os.MkdirAll(path.Join(p, "logs"), ice.MOD_DIR) - os.MkdirAll(path.Join(p, "bin"), ice.MOD_DIR) - os.MkdirAll(p, ice.MOD_DIR) - - // 复制 - name := path.Base(strings.TrimSuffix(strings.TrimSuffix(m.Conf(TMUX, "meta.source"), ".tar.gz"), "zip")) - m.Cmd(cli.SYSTEM, "cp", "-r", path.Join(m.Conf(code.INSTALL, kit.META_PATH), name, "src/redis-cli"), path.Join(p, "bin")) - m.Cmd(cli.SYSTEM, "cp", "-r", path.Join(m.Conf(code.INSTALL, kit.META_PATH), name, "src/redis-server"), path.Join(p, "bin")) - m.Cmd(cli.SYSTEM, "cp", "-r", path.Join(m.Conf(code.INSTALL, kit.META_PATH), name, "src/redis-benchmark"), path.Join(p, "bin")) - - // 启动 - m.Option(cli.CMD_DIR, p) - m.Cmdy(cli.DAEMON, "bin/redis-server", "--port", port) + "build": {Name: "build", Help: "构建", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(code.INSTALL, "build", m.Conf(TMUX, kit.META_SOURCE)) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) > 0 && arg[0] != "" { - m.Cmdy(cli.SYSTEM, "bin/redis-cli", "-p", arg[0], kit.Split(kit.Select("info", arg, 1))) - return - } - - m.Cmd(cli.DAEMON).Table(func(index int, value map[string]string, head []string) { - if strings.HasPrefix(value[kit.MDB_NAME], "bin/redis") { - m.Push(kit.MDB_TIME, value[kit.MDB_TIME]) - m.Push(kit.MDB_PORT, path.Base(value[kit.MDB_DIR])) - m.Push(kit.MDB_DIR, value[kit.MDB_DIR]) - m.Push(kit.MDB_STATUS, value[kit.MDB_STATUS]) - m.Push(kit.MDB_PID, value[kit.MDB_PID]) - m.Push(kit.MDB_NAME, value[kit.MDB_NAME]) - } - }) - m.Sort("time", "time_r") }}, + TEXT: {Name: "text 保存:button 清空: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]) diff --git a/misc/tmux/tmux.shy b/misc/tmux/tmux.shy index 01f3c622..b66c9f63 100644 --- a/misc/tmux/tmux.shy +++ b/misc/tmux/tmux.shy @@ -7,7 +7,7 @@ refer "官网" ` premenu field tmux web.code.tmux.tmux -field tmux web.code.inner args `[ usr/install/tmux-3.1b input.c ]` +field tmux web.code.inner args `[ usr/install/tmux-3.1b cmd-bind-key.c ]` chapter "安装" section "libevent" @@ -18,14 +18,23 @@ tar xvf libevent-2.1.12-stable.tar.gz && cd libevent-2.1.12-stable make -j8 make install ` -section "ncureses" +section "ncurses" spark shell ` wget https://invisible-island.net/datafiles/release/ncurses.tar.gz -tar xvf ncurese.tar.gz && cd ncurese-6.2 +tar xvf ncurses.tar.gz && cd ncurses-6.2 ./configure make -j8 make install ` +section "tmux" +spark shell ` +wget https://github.com/tmux/tmux/releases/download/3.1b/tmux-3.1b.tar.gz +tar xvf tmux-3.1b.tar.gz && cd tmux-3.1b +./configure +make -j8 +make install +` + chapter "应用" field text web.code.tmux.text field buffer web.code.tmux.buffer args 0