diff --git a/base/cli/daemon.go b/base/cli/daemon.go index 3300b010..af4de0da 100644 --- a/base/cli/daemon.go +++ b/base/cli/daemon.go @@ -1,6 +1,8 @@ package cli import ( + "io" + ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/mdb" kit "github.com/shylinux/toolkits" @@ -10,13 +12,20 @@ import ( ) func _daemon_show(m *ice.Message, cmd *exec.Cmd, out, err string) { - if f, p, e := kit.Create(out); m.Assert(e) { + if w, ok := m.Optionv(CMD_STDOUT).(io.Writer); ok { + cmd.Stdout = w + cmd.Stderr = w + } else if f, p, e := kit.Create(out); m.Assert(e) { m.Log_EXPORT(kit.MDB_META, DAEMON, CMD_STDOUT, p) + m.Optionv(CMD_STDOUT, f) cmd.Stdout = f cmd.Stderr = f } - if f, p, e := kit.Create(err); m.Assert(e) { + if w, ok := m.Optionv(CMD_STDERR).(io.Writer); ok { + cmd.Stderr = w + } else if f, p, e := kit.Create(err); m.Assert(e) { m.Log_EXPORT(kit.MDB_META, DAEMON, CMD_STDERR, p) + m.Optionv(CMD_STDERR, f) cmd.Stderr = f } @@ -40,6 +49,12 @@ func _daemon_show(m *ice.Message, cmd *exec.Cmd, out, err string) { m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, h, kit.MDB_STATUS, Status.Stop) } + if w, ok := m.Optionv(CMD_STDOUT).(io.Closer); ok { + w.Close() + } + if w, ok := m.Optionv(CMD_STDERR).(io.Closer); ok { + w.Close() + } }) } @@ -68,6 +83,7 @@ func init() { DAEMON: {Name: "daemon hash auto 添加 清理", Help: "守护进程", Action: map[string]*ice.Action{ RESTART: {Name: "restart", Help: "重启", Hand: func(m *ice.Message, arg ...string) { m.Cmd(DAEMON, STOP) + m.Sleep("1s") m.Cmd(DAEMON, START) }}, START: {Name: "start cmd env dir", Help: "添加", Hand: func(m *ice.Message, arg ...string) { diff --git a/base/nfs/nfs.go b/base/nfs/nfs.go index 9d81d795..ea50c8e8 100644 --- a/base/nfs/nfs.go +++ b/base/nfs/nfs.go @@ -286,6 +286,7 @@ const ( SAVE = "save" COPY = "copy" LINK = "link" + TAIL = "tail" ) const ( DIR_ROOT = "dir_root" @@ -316,14 +317,28 @@ var Index = &ice.Context{Name: "nfs", Help: "存储模块", ), )}, TRASH: {Name: TRASH, Help: "删除", Value: kit.Data("path", "var/trash")}, + + TAIL: {Name: TAIL, Help: "跟踪", Value: kit.Data()}, }, Commands: map[string]*ice.Command{ ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Load() m.Cmd(mdb.SEARCH, mdb.CREATE, DIR) m.Cmd(mdb.RENDER, mdb.CREATE, DIR) m.Cmd(mdb.SEARCH, mdb.CREATE, FILE, m.Prefix(FILE)) m.Cmd(mdb.RENDER, mdb.CREATE, FILE, m.Prefix(FILE)) + m.Richs(TAIL, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { + value = kit.GetMeta(value) + m.Option(kit.MDB_HASH, key) + m.Cmd(TAIL, mdb.CREATE, + kit.MDB_FILE, kit.Format(value[kit.MDB_FILE]), + kit.MDB_NAME, kit.Format(value[kit.MDB_NAME]), + ) + }) + }}, + ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Save() }}, DIR: {Name: "dir path field... auto 上传", Help: "目录", Action: map[string]*ice.Action{ mdb.SEARCH: {Name: "search type name text", Help: "搜索", Hand: func(m *ice.Message, arg ...string) { @@ -385,7 +400,42 @@ var Index = &ice.Context{Name: "nfs", Help: "存储模块", TRASH: {Name: "trash file", Help: "删除", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { _file_trash(m, arg[0]) }}, + + TAIL: {Name: "tail hash id auto create", Help: "文件", Action: map[string]*ice.Action{ + mdb.CREATE: {Name: "create file name", Help: "创建", Hand: func(m *ice.Message, arg ...string) { + if m.Option(kit.MDB_HASH) == "" { + m.Cmdy(mdb.INSERT, TAIL, "", mdb.HASH, arg) + m.Option(kit.MDB_HASH, m.Result()) + } + h := m.Option(kit.MDB_HASH) + for _, file := range kit.Split(m.Option(kit.MDB_FILE), ",") { + func(file string) { + r, w := io.Pipe() + m.Go(func(msg *ice.Message) { + for bio := bufio.NewScanner(r); bio.Scan(); { + m.Grow(TAIL, kit.Keys(kit.MDB_HASH, h), kit.Dict( + kit.MDB_FILE, file, kit.MDB_TEXT, bio.Text(), + )) + } + }) + m.Option(cli.CMD_STDOUT, w) + m.Option(cli.CMD_STDERR, w) + m.Cmd(cli.DAEMON, "tail", "-n", "0", "-f", file) + }(file) + } + }}, + mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(mdb.DELETE, TAIL, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) + }}, + }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Option(mdb.FIELDS, kit.Select("time,hash,count,name,file", kit.Select("time,id,file,text", mdb.DETAIL, len(arg) > 1), len(arg) > 0)) + m.Cmdy(mdb.SELECT, TAIL, "", mdb.ZONE, arg) + m.PushAction(kit.Select("", mdb.REMOVE, len(arg) == 0)) + if len(arg) == 1 { + m.Option(ice.MSG_CONTROL, "_page") + } + }}, }, } -func init() { ice.Index.Register(Index, nil, DIR, CAT, SAVE, COPY, LINK, TRASH) } +func init() { ice.Index.Register(Index, nil, DIR, CAT, SAVE, COPY, LINK, TRASH, TAIL) } diff --git a/base/web/serve.go b/base/web/serve.go index 724d977b..fd1f85a7 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -127,7 +127,6 @@ func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.Respon // 用户请求 msg.Option(ice.MSG_OUTPUT, "") - msg.Option("cache.limit", "10") msg.Option(ice.MSG_METHOD, r.Method) msg.Option(ice.MSG_USERWEB, kit.Select(msg.Conf(SHARE, "meta.domain"), r.Header.Get("Referer"))) msg.Option(ice.MSG_USERIP, r.Header.Get(ice.MSG_USERIP)) @@ -267,7 +266,6 @@ func init() { Commands: map[string]*ice.Command{ SERVE: {Name: "serve name auto start", Help: "服务器", Action: map[string]*ice.Action{ gdb.START: {Name: "start dev= name=self proto=http host= port=9020", Help: "启动", Hand: func(m *ice.Message, arg ...string) { - m.Debug("what %v %v", m.Option("name"), m.Option("dev")) if cli.NodeInfo(m, SERVER, ice.Info.HostName); m.Option(tcp.PORT) == "random" { m.Option(tcp.PORT, m.Cmdx(tcp.PORT, aaa.Right)) }