1
0
mirror of https://shylinux.com/x/icebergs synced 2025-05-01 11:09:23 +08:00
This commit is contained in:
shaoying 2020-06-16 09:45:07 +08:00
parent b25ca6233f
commit 4629219b30
13 changed files with 349 additions and 157 deletions

View File

@ -4,71 +4,17 @@ import (
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"bytes"
"fmt"
"os" "os"
"os/exec"
"os/user" "os/user"
"path" "path"
"runtime" "runtime"
"strings" "strings"
) )
func _system_run(m *ice.Message, cmd *exec.Cmd) {
out := bytes.NewBuffer(make([]byte, 0, 1024))
err := bytes.NewBuffer(make([]byte, 0, 1024))
cmd.Stdout = out
cmd.Stderr = err
if e := cmd.Run(); e != nil {
m.Warn(e != nil, "%v run: %s", nil, kit.Select(e.Error(), err.String()))
} else {
m.Cost("%v exit: %v", nil, cmd.ProcessState.ExitCode())
}
m.Push("code", int(cmd.ProcessState.ExitCode()))
m.Echo(out.String())
}
func _daemon_run(m *ice.Message, cmd *exec.Cmd, out, err string) {
if out != "" {
if f, p, e := kit.Create(out); m.Assert(e) {
m.Log_EXPORT("stdout", p)
cmd.Stdout = f
cmd.Stderr = f
}
}
if err != "" {
if f, p, e := kit.Create(err); m.Assert(e) {
m.Log_EXPORT("stderr", p)
cmd.Stderr = f
}
}
cmd.Env = append(cmd.Env, fmt.Sprintf("PATH=%s", os.Getenv("PATH")))
if e := cmd.Start(); m.Warn(e != nil, "%v start: %s", cmd.Args, e) {
return
}
m.Rich("daemon", nil, kit.Dict(kit.MDB_NAME, cmd.Process.Pid, "status", "running"))
m.Echo("%d", cmd.Process.Pid)
m.Gos(m, func(m *ice.Message) {
if e := cmd.Wait(); e != nil {
m.Warn(e != nil, "%v wait: %s", cmd.Args, e)
} else {
m.Cost("%v exit: %v", cmd.Args, cmd.ProcessState.ExitCode())
m.Rich("daemon", nil, func(key string, value map[string]interface{}) {
value["status"] = "exited"
})
}
})
}
var Index = &ice.Context{Name: "cli", Help: "命令模块", var Index = &ice.Context{Name: "cli", Help: "命令模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
ice.CLI_RUNTIME: {Name: "runtime", Help: "运行环境", Value: kit.Dict()}, ice.CLI_RUNTIME: {Name: "runtime", Help: "运行环境", Value: kit.Dict()},
ice.CLI_SYSTEM: {Name: "system", Help: "系统命令", Value: kit.Data()},
ice.CLI_DAEMON: {Name: "daemon", Help: "守护进程", Value: kit.Data(kit.MDB_SHORT, "name")},
"python": {Name: "python", Help: "系统命令", Value: kit.Data("python", "python", "pip", "pip")},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
@ -119,49 +65,6 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
ice.CLI_RUNTIME: {Name: "runtime", Help: "运行环境", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.CLI_RUNTIME: {Name: "runtime", Help: "运行环境", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmdy(ice.CTX_CONFIG, ice.CLI_RUNTIME, arg) m.Cmdy(ice.CTX_CONFIG, ice.CLI_RUNTIME, arg)
}}, }},
ice.CLI_SYSTEM: {Name: "system", Help: "系统命令", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
cmd := exec.Command(arg[0], arg[1:]...)
// 运行目录
cmd.Dir = m.Option("cmd_dir")
if len(cmd.Dir) > 0 {
m.Info("dir: %s", cmd.Dir)
if _, e := os.Stat(cmd.Dir); e != nil && os.IsNotExist(e) {
os.MkdirAll(cmd.Dir, 0777)
}
}
// 环境变量
env := kit.Simple(m.Optionv("cmd_env"))
for i := 0; i < len(env)-1; i += 2 {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", env[i], env[i+1]))
}
if len(cmd.Env) > 0 {
m.Info("env: %s", cmd.Env)
}
switch m.Option("cmd_type") {
case "daemon":
_daemon_run(m, cmd, m.Option("cmd_stdout"), m.Option("cmd_stderr"))
default:
_system_run(m, cmd)
}
}},
ice.CLI_DAEMON: {Name: "daemon", Help: "守护进程", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option("cmd_type", "daemon")
m.Cmdy(ice.CLI_SYSTEM, arg)
}},
"python": {Name: "python", Help: "运行环境", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
prefix := []string{ice.CLI_SYSTEM, m.Conf("python", "meta.python")}
switch arg[0] {
case "qrcode":
m.Cmdy(prefix, "-c", fmt.Sprintf(`import pyqrcode; print(pyqrcode.create('%s').terminal(module_color='%s', quiet_zone=1))`, kit.Select("hello world", arg, 1), kit.Select("blue", arg, 2)))
case "install":
m.Cmdy(prefix[:1], m.Conf("python", "meta.pip"), "install", arg[1:])
default:
m.Cmdy(prefix, arg)
}
}},
}, },
} }

76
base/cli/daemon.go Normal file
View File

@ -0,0 +1,76 @@
package cli
import (
ice "github.com/shylinux/icebergs"
kit "github.com/shylinux/toolkits"
"fmt"
"os"
"os/exec"
"strings"
)
var DAEMON = ice.Name("daemon", Index)
const (
StatusError = "error"
StatusStart = "start"
StatusClose = "close"
)
func _daemon_show(m *ice.Message, cmd *exec.Cmd, out, err string) {
if f, p, e := kit.Create(out); m.Assert(e) {
m.Log_EXPORT(kit.MDB_META, DAEMON, CMD_STDOUT, p)
cmd.Stdout = f
cmd.Stderr = f
}
if f, p, e := kit.Create(err); m.Assert(e) {
m.Log_EXPORT(kit.MDB_META, DAEMON, CMD_STDERR, p)
cmd.Stderr = f
}
cmd.Env = append(cmd.Env, fmt.Sprintf("PATH=%s", os.Getenv("PATH")))
if e := cmd.Start(); m.Warn(e != nil, "%v start: %s", cmd.Args, e) {
return
}
h := m.Rich(DAEMON, nil, kit.Dict(
kit.MDB_TYPE, ice.TYPE_SHELL, kit.MDB_NAME, cmd.Process.Pid, kit.MDB_TEXT, strings.Join(cmd.Args, " "),
kit.MDB_EXTRA, kit.Dict(
kit.MDB_STATUS, StatusStart,
CMD_STDOUT, out,
CMD_STDERR, err,
),
))
m.Log_EXPORT(kit.MDB_META, DAEMON, kit.MDB_KEY, h, kit.MDB_PID, cmd.Process.Pid)
m.Echo("%d", cmd.Process.Pid)
m.Gos(m, func(m *ice.Message) {
if e := cmd.Wait(); e != nil {
m.Warn(e != nil, "%v wait: %s", cmd.Args, e)
m.Richs(DAEMON, nil, h, func(key string, value map[string]interface{}) {
kit.Value(value, kit.Keys(kit.MDB_EXTRA, kit.MDB_STATUS), StatusError)
kit.Value(value, kit.Keys(kit.MDB_EXTRA, kit.MDB_ERROR), e)
})
} else {
defer m.Cost("%v exit: %v", cmd.Args, cmd.ProcessState.ExitCode())
m.Richs(DAEMON, nil, h, func(key string, value map[string]interface{}) {
kit.Value(value, kit.Keys(kit.MDB_EXTRA, kit.MDB_STATUS), StatusClose)
})
}
})
}
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
DAEMON: {Name: "daemon", Help: "守护进程", Value: kit.Data()},
},
Commands: map[string]*ice.Command{
DAEMON: {Name: "daemon cmd arg...", Help: "守护进程", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(CMD_TYPE, DAEMON)
m.Cmdy(SYSTEM, arg)
}},
},
}, nil)
}

36
base/cli/python.go Normal file
View File

@ -0,0 +1,36 @@
package cli
import (
ice "github.com/shylinux/icebergs"
kit "github.com/shylinux/toolkits"
"fmt"
)
var PYTHON = ice.Name("python", Index)
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
PYTHON: {Name: "python", Help: "脚本命令", Value: kit.Data(
PYTHON, "python", "pip", "pip",
"qrcode", `import pyqrcode; print(pyqrcode.create('%s').terminal(module_color='%s', quiet_zone=1))`,
)},
},
Commands: map[string]*ice.Command{
PYTHON: {Name: "python cmd arg...", Help: "脚本命令", Action: map[string]*ice.Action{
"install": {Name: "install arg...", Help: "安装", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SYSTEM, m.Conf(PYTHON, "meta.pip"), "install", arg)
}},
"qrcode": {Name: "qrcode text color", Help: "安装", Hand: func(m *ice.Message, arg ...string) {
prefix := []string{SYSTEM, m.Conf(PYTHON, kit.Keys(kit.MDB_META, PYTHON))}
m.Cmdy(prefix, "-c", fmt.Sprintf(m.Conf(PYTHON, "meta.qrcode"),
kit.Select("hello world", arg, 0), kit.Select("blue", arg, 1)))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
prefix := []string{SYSTEM, m.Conf(PYTHON, kit.Keys(kit.MDB_META, PYTHON))}
m.Cmdy(prefix, arg)
}},
},
}, nil)
}

80
base/cli/system.go Normal file
View File

@ -0,0 +1,80 @@
package cli
import (
ice "github.com/shylinux/icebergs"
kit "github.com/shylinux/toolkits"
"bytes"
"fmt"
"os"
"os/exec"
)
var SYSTEM = ice.Name("system", Index)
const (
CMD_STDOUT = "cmd_stdout"
CMD_STDERR = "cmd_stderr"
CMD_TYPE = "cmd_type"
CMD_DIR = "cmd_dir"
CMD_ENV = "cmd_env"
CMD_ERR = "cmd_err"
CMD_OUT = "cmd_out"
CMD_CODE = "cmd_code"
)
func _system_show(m *ice.Message, cmd *exec.Cmd) {
out := bytes.NewBuffer(make([]byte, 0, 1024))
err := bytes.NewBuffer(make([]byte, 0, 1024))
cmd.Stdout = out
cmd.Stderr = err
if e := cmd.Run(); e != nil {
m.Warn(e != nil, "%v run: %s", cmd.Args, kit.Select(e.Error(), err.String()))
} else {
defer m.Cost("%v exit: %v out: %v err: %v ", cmd.Args, cmd.ProcessState.ExitCode(), out.Len(), err.Len())
}
m.Push(CMD_CODE, int(cmd.ProcessState.ExitCode()))
m.Push(CMD_ERR, err.String())
m.Push(CMD_OUT, out.String())
m.Echo(out.String())
}
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
SYSTEM: {Name: "system", Help: "系统命令", Value: kit.Data()},
},
Commands: map[string]*ice.Command{
SYSTEM: {Name: "system cmd arg...", Help: "系统命令", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
cmd := exec.Command(arg[0], arg[1:]...)
// 运行目录
if cmd.Dir = m.Option(CMD_DIR); len(cmd.Dir) > 0 {
m.Log_EXPORT(kit.MDB_META, SYSTEM, CMD_DIR, cmd.Dir)
if _, e := os.Stat(cmd.Dir); e != nil && os.IsNotExist(e) {
os.MkdirAll(cmd.Dir, ice.DIR_MOD)
}
}
// 环境变量
env := kit.Simple(m.Optionv(CMD_ENV))
for i := 0; i < len(env)-1; i += 2 {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", env[i], env[i+1]))
}
if len(cmd.Env) > 0 {
m.Log_EXPORT(kit.MDB_META, SYSTEM, CMD_ENV, cmd.Env)
}
switch m.Option(CMD_TYPE) {
case DAEMON:
_daemon_show(m, cmd, m.Option(CMD_STDOUT), m.Option(CMD_STDERR))
default:
_system_show(m, cmd)
}
}},
},
}, nil)
}

View File

@ -130,6 +130,7 @@ func (f *Frame) parse(m *ice.Message, line string) *Frame {
// 解析选项 // 解析选项
ln := []string{} ln := []string{}
msg := m.Spawns(f.target) msg := m.Spawns(f.target)
msg.Option("cache.limit", 10)
for i := 0; i < len(ls); i++ { for i := 0; i < len(ls); i++ {
if ls[i] == "--" { if ls[i] == "--" {
ln = append(ln, ls[i+1:]...) ln = append(ln, ls[i+1:]...)

View File

@ -13,11 +13,34 @@ import (
var CACHE = ice.Name("cache", Index) var CACHE = ice.Name("cache", Index)
func _cache_list(m *ice.Message) { func _cache_list(m *ice.Message, key string) {
m.Grows(CACHE, nil, "", "", func(index int, value map[string]interface{}) { if key == "" {
m.Push("", value) m.Grows(CACHE, nil, "", "", func(index int, value map[string]interface{}) {
m.Push("", value, []string{kit.MDB_TIME, kit.MDB_ID, kit.MDB_TYPE})
m.Push(kit.MDB_SIZE, kit.FmtSize(kit.Int64(value[kit.MDB_SIZE])))
m.Push("", value, []string{kit.MDB_NAME, kit.MDB_TEXT, kit.MDB_DATA})
})
m.Sort(kit.MDB_ID, "int_r")
return
}
m.Richs(CACHE, nil, key, func(key string, value map[string]interface{}) {
m.Push("detail", value)
m.Push(kit.MDB_KEY, "操作")
m.Push(kit.MDB_VALUE, `<input type="button" value="运行">`)
}) })
} }
func _cache_show(m *ice.Message, kind, name, text string, arg ...string) {
if kind == "" && name == "" {
m.Richs(CACHE, nil, m.Option(kit.MDB_DATA), func(key string, value map[string]interface{}) {
kind = kit.Format(value[kit.MDB_TYPE])
name = kit.Format(value[kit.MDB_NAME])
text = kit.Format(value[kit.MDB_TEXT])
arg = kit.Simple(value[kit.MDB_EXTRA])
m.Log_EXPORT(kit.MDB_META, CACHE, kit.MDB_TYPE, kind, kit.MDB_NAME, name)
})
}
FavorShow(m, kind, name, text, kit.Simple(arg)...)
}
func _cache_save(m *ice.Message, method, kind, name, text string, arg ...string) { func _cache_save(m *ice.Message, method, kind, name, text string, arg ...string) {
size := kit.Int(kit.Select(kit.Format(len(text)), arg, 1)) size := kit.Int(kit.Select(kit.Format(len(text)), arg, 1))
if method == "add" && size > 512 { if method == "add" && size > 512 {
@ -56,7 +79,7 @@ func _cache_save(m *ice.Message, method, kind, name, text string, arg ...string)
m.Push("size", size) m.Push("size", size)
m.Push("data", h) m.Push("data", h)
} }
func _cache_show(m *ice.Message, key, file string) { func _cache_watch(m *ice.Message, key, file string) {
if m.Richs(CACHE, nil, key, func(key string, value map[string]interface{}) { if m.Richs(CACHE, nil, key, func(key string, value map[string]interface{}) {
if value["file"] == "" { if value["file"] == "" {
if f, _, e := kit.Create(file); m.Assert(e) { if f, _, e := kit.Create(file); m.Assert(e) {
@ -89,7 +112,7 @@ func _cache_catch(m *ice.Message, arg ...string) []string {
// 导入数据 // 导入数据
f.Seek(0, os.SEEK_SET) f.Seek(0, os.SEEK_SET)
if n, e := io.Copy(o, f); m.Assert(e) { if n, e := io.Copy(o, f); m.Assert(e) {
m.Log_IMPORT(kit.MDB_FILE, kit.FmtSize(n), kit.MDB_SIZE, p) m.Log_IMPORT(kit.MDB_FILE, p, kit.MDB_SIZE, kit.FmtSize(n))
arg = kit.Simple(arg[0], arg[1], arg[2], p, p, n) arg = kit.Simple(arg[0], arg[1], arg[2], p, p, n)
} }
} }
@ -126,7 +149,7 @@ func _cache_download(m *ice.Message, r *http.Response, arg ...string) []string {
// 导入数据 // 导入数据
if n, e := o.Write(buf); m.Assert(e) { if n, e := o.Write(buf); m.Assert(e) {
m.Log(ice.LOG_IMPORT, "%s: %s", kit.FmtSize(int64(n)), p) m.Log_IMPORT(kit.MDB_FILE, p, kit.MDB_SIZE, kit.FmtSize(int64(n)))
arg = kit.Simple(arg[0], arg[1], arg[2], p, p, n) arg = kit.Simple(arg[0], arg[1], arg[2], p, p, n)
} }
} }
@ -134,6 +157,10 @@ func _cache_download(m *ice.Message, r *http.Response, arg ...string) []string {
return arg return arg
} }
func CacheCatch(m *ice.Message, kind, name string) *ice.Message {
_cache_catch(m, "catch", kind, name)
return m
}
func init() { func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
@ -142,9 +169,20 @@ func init() {
)}, )},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
CACHE: {Name: "cache", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { CACHE: {Name: "cache data=auto auto", Help: "缓存池", Action: map[string]*ice.Action{
kit.MDB_CREATE: {Name: "create type name text arg...", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
_cache_save(m, "add", arg[0], arg[1], arg[2], arg[3:]...)
}},
kit.MDB_SHOW: {Name: "show type name text arg...", Help: "运行", Hand: func(m *ice.Message, arg ...string) {
if len(arg) > 2 {
_cache_show(m, arg[0], arg[1], arg[2], arg[3:]...)
} else {
_cache_show(m, "", "", "")
}
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
_cache_list(m) _cache_list(m, "")
return return
} }
@ -162,7 +200,9 @@ func init() {
case "add": case "add":
_cache_save(m, arg[0], arg[1], arg[2], arg[3], arg[4:]...) _cache_save(m, arg[0], arg[1], arg[2], arg[3], arg[4:]...)
case "watch": case "watch":
_cache_show(m, arg[1], arg[2]) _cache_watch(m, arg[1], arg[2])
default:
_cache_list(m, arg[0])
} }
}}, }},
"/cache/": {Name: "/cache/", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "/cache/": {Name: "/cache/", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -41,7 +41,24 @@ func _favor_list(m *ice.Message, zone, id string, fields ...string) {
}) })
}) })
} }
func _favor_show(m *ice.Message, zone, id string, arg ...string) { func _favor_show(m *ice.Message, kind string, name, text interface{}, arg ...string) {
if kind == "" && name == "" {
m.Richs(FAVOR, nil, m.Option(kit.MDB_ZONE), func(key string, val map[string]interface{}) {
m.Grows(FAVOR, kit.Keys(kit.MDB_HASH, key), kit.MDB_ID, m.Option(kit.MDB_ID), func(index int, value map[string]interface{}) {
kind = kit.Format(value[kit.MDB_TYPE])
name = kit.Format(value[kit.MDB_NAME])
text = kit.Format(value[kit.MDB_TEXT])
arg = kit.Simple(value[kit.MDB_EXTRA])
m.Log_EXPORT(kit.MDB_META, FAVOR, kit.MDB_TYPE, kind, kit.MDB_NAME, name)
})
})
}
if cmd := m.Conf(FAVOR, kit.Keys("meta.render", kind)); cmd != "" {
m.Cmdy(cmd, kind, name, text, arg)
return
}
m.Cmdy(kind, "action", "show", kind, name, text, arg)
} }
func _favor_sync(m *ice.Message, zone, route, favor string, arg ...string) { func _favor_sync(m *ice.Message, zone, route, favor string, arg ...string) {
m.Richs(FAVOR, nil, zone, func(key string, val map[string]interface{}) { m.Richs(FAVOR, nil, zone, func(key string, val map[string]interface{}) {
@ -126,7 +143,7 @@ func _favor_modify(m *ice.Message, zone, id, pro, set, old string) {
}) })
}) })
} }
func _favor_insert(m *ice.Message, zone, kind, name, text string, arg ...string) { func _favor_insert(m *ice.Message, zone, kind, name interface{}, text interface{}, arg ...string) {
m.Richs(FAVOR, nil, zone, func(key string, val map[string]interface{}) { m.Richs(FAVOR, nil, zone, func(key string, val map[string]interface{}) {
kit.Value(val, kit.Keys(kit.MDB_META, kit.MDB_TIME), m.Time()) kit.Value(val, kit.Keys(kit.MDB_META, kit.MDB_TIME), m.Time())
@ -218,13 +235,17 @@ func _favor_export(m *ice.Message, file string) {
m.Log_EXPORT(kit.MDB_FILE, p, kit.MDB_COUNT, count) m.Log_EXPORT(kit.MDB_FILE, p, kit.MDB_COUNT, count)
} }
func FavorInsert(m *ice.Message, zone, kind, name, text string, extra ...string) { func FavorInsert(m *ice.Message, zone, kind string, name interface{}, text interface{}, extra ...string) {
_favor_create(m, zone) _favor_create(m, zone)
_favor_insert(m, zone, kind, name, text, extra...) _favor_insert(m, zone, kind, name, text, extra...)
} }
func FavorList(m *ice.Message, favor, id string, fields ...string) { func FavorList(m *ice.Message, favor, id string, fields ...string) {
_favor_list(m, favor, id, fields...) _favor_list(m, favor, id, fields...)
} }
func FavorShow(m *ice.Message, kind string, name, text interface{}, arg ...string) *ice.Message {
_favor_show(m, kind, name, text, arg...)
return m
}
func init() { func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{
@ -264,8 +285,12 @@ func init() {
kit.MDB_SYNC: {Name: "sync route favor", Help: "同步", Hand: func(m *ice.Message, arg ...string) { kit.MDB_SYNC: {Name: "sync route favor", Help: "同步", Hand: func(m *ice.Message, arg ...string) {
_favor_sync(m, m.Option(kit.MDB_ZONE), arg[0], arg[1], arg[2:]...) _favor_sync(m, m.Option(kit.MDB_ZONE), arg[0], arg[1], arg[2:]...)
}}, }},
kit.MDB_SHOW: {Name: "show arg...", Help: "运行", Hand: func(m *ice.Message, arg ...string) { kit.MDB_SHOW: {Name: "show type name text arg...", Help: "运行", Hand: func(m *ice.Message, arg ...string) {
_favor_show(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), arg...) if len(arg) > 2 {
_favor_show(m, arg[0], arg[1], arg[2], arg[3:]...)
} else {
_favor_show(m, "", "", "")
}
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
fields := []string{kit.MDB_TIME, kit.MDB_ID, kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT} fields := []string{kit.MDB_TIME, kit.MDB_ID, kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT}

View File

@ -265,7 +265,7 @@ func (web *Frame) HandleCmd(m *ice.Message, key string, cmd *ice.Command) {
defer func() { msg.Cost("%s %v %v", r.URL.Path, msg.Optionv("cmds"), msg.Format("append")) }() defer func() { msg.Cost("%s %v %v", r.URL.Path, msg.Optionv("cmds"), msg.Format("append")) }()
if u, e := url.Parse(r.Header.Get("Referer")); e == nil { if u, e := url.Parse(r.Header.Get("Referer")); e == nil {
for k, v := range u.Query() { for k, v := range u.Query() {
msg.Info("%s: %v", k, v) msg.Logs("refer", k, v)
msg.Option(k, v) msg.Option(k, v)
} }
} }
@ -307,7 +307,7 @@ func (web *Frame) HandleCmd(m *ice.Message, key string, cmd *ice.Command) {
r.ParseMultipartForm(kit.Int64(kit.Select(r.Header.Get("Content-Length"), "4096"))) r.ParseMultipartForm(kit.Int64(kit.Select(r.Header.Get("Content-Length"), "4096")))
if r.ParseForm(); len(r.PostForm) > 0 { if r.ParseForm(); len(r.PostForm) > 0 {
for k, v := range r.PostForm { for k, v := range r.PostForm {
msg.Info("%s: %v", k, v) msg.Logs("form", k, v)
} }
} }
} }
@ -577,6 +577,10 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
} }
}) })
}})) }}))
m.Conf(ice.WEB_FAVOR, "meta.render.bench", m.AddCmd(&ice.Command{Name: "render type name text arg...", Help: "渲染引擎", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmdy("web.code.bench", "action", "show", arg)
}}))
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save(ice.WEB_SPIDE, ice.WEB_SERVE, ice.WEB_GROUP, ice.WEB_LABEL, m.Save(ice.WEB_SPIDE, ice.WEB_SERVE, ice.WEB_GROUP, ice.WEB_LABEL,

View File

@ -1,5 +1,10 @@
package ice package ice
const (
DIR_MOD = 0750
FILE_MOD = 0640
)
const ( // ICE const ( // ICE
ICE_CHAN = 10 ICE_CHAN = 10
ICE_INIT = "_init" ICE_INIT = "_init"

View File

@ -28,7 +28,7 @@ func _bench_list(m *ice.Message, zone string, id string, field ...interface{}) {
m.Push(zone, value, []string{ m.Push(zone, value, []string{
kit.MDB_ZONE, kit.MDB_ID, kit.MDB_TYPE, kit.MDB_ZONE, kit.MDB_ID, kit.MDB_TYPE,
kit.MDB_NAME, NCONN, NREQS, kit.MDB_TEXT, kit.MDB_NAME, NCONN, NREQS, kit.MDB_TEXT,
}) }, val)
}) })
return return
} }
@ -109,17 +109,23 @@ func init() {
kit.MDB_MODIFY: {Name: "modify key value old", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { kit.MDB_MODIFY: {Name: "modify key value old", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
_bench_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), arg[0], arg[1], kit.Select("", arg, 2)) _bench_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), arg[0], arg[1], kit.Select("", arg, 2))
}}, }},
kit.MDB_SHOW: {Name: "show", Help: "运行", Hand: func(m *ice.Message, arg ...string) { kit.MDB_SHOW: {Name: "show type name text arg...", Help: "运行", Hand: func(m *ice.Message, arg ...string) {
m.Richs(BENCH, nil, m.Option(kit.MDB_ZONE), func(key string, val map[string]interface{}) { if len(arg) < 2 {
m.Grows(BENCH, kit.Keys(kit.MDB_HASH, key), kit.MDB_ID, m.Option(kit.MDB_ID), func(index int, value map[string]interface{}) { m.Richs(BENCH, nil, m.Option(kit.MDB_ZONE), func(key string, val map[string]interface{}) {
m.Option(kit.MDB_TEXT, value[kit.MDB_TEXT]) m.Grows(BENCH, kit.Keys(kit.MDB_HASH, key), kit.MDB_ID, m.Option(kit.MDB_ID), func(index int, value map[string]interface{}) {
m.Option(NCONN, value[NCONN]) arg = kit.Simple(value[kit.MDB_TYPE], value[kit.MDB_NAME], value[kit.MDB_TEXT], value[kit.MDB_EXTRA])
m.Option(NREQS, value[NREQS]) })
}) })
}) }
if len(arg) > 2 {
m.Option(kit.MDB_TEXT, arg[2])
for i := 3; i < len(arg)-1; i++ {
m.Option(arg[i], arg[i+1])
}
}
list := []*http.Request{} list := []*http.Request{}
target := kit.Select(m.Option(kit.MDB_TEXT)) target := kit.Select(m.Option(kit.MDB_TEXT), arg, 2)
for _, v := range strings.Split(target, ",") { for _, v := range strings.Split(target, ",") {
switch ls := kit.Split(v); ls[0] { switch ls := kit.Split(v); ls[0] {
case http.MethodPost: case http.MethodPost:

View File

@ -2,6 +2,7 @@ package code
import ( import (
"github.com/shylinux/icebergs" "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/web" "github.com/shylinux/icebergs/base/web"
"github.com/shylinux/toolkits" "github.com/shylinux/toolkits"
@ -22,7 +23,7 @@ func _pprof_list(m *ice.Message, zone string, id string, field ...interface{}) {
val = val[kit.MDB_META].(map[string]interface{}) val = val[kit.MDB_META].(map[string]interface{})
if zone = kit.Format(kit.Value(val, kit.MDB_ZONE)); id == "" { if zone = kit.Format(kit.Value(val, kit.MDB_ZONE)); id == "" {
m.Grows(PPROF, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { m.Grows(PPROF, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) {
// 查看信息 // 列表信息
m.Push("操作", `<input type="button" value="运行">`) m.Push("操作", `<input type="button" value="运行">`)
m.Push(zone, value, []string{ m.Push(zone, value, []string{
kit.MDB_ZONE, kit.MDB_ID, kit.MDB_TYPE, kit.MDB_ZONE, kit.MDB_ID, kit.MDB_TYPE,
@ -32,7 +33,7 @@ func _pprof_list(m *ice.Message, zone string, id string, field ...interface{}) {
return return
} }
m.Grows(PPROF, kit.Keys(kit.MDB_HASH, key), kit.MDB_ID, id, func(index int, value map[string]interface{}) { m.Grows(PPROF, kit.Keys(kit.MDB_HASH, key), kit.MDB_ID, id, func(index int, value map[string]interface{}) {
// 查看信息 // 详细信息
m.Push("detail", value) m.Push("detail", value)
m.Push(kit.MDB_KEY, "操作") m.Push(kit.MDB_KEY, "操作")
m.Push(kit.MDB_VALUE, `<input type="button" value="运行">`) m.Push(kit.MDB_VALUE, `<input type="button" value="运行">`)
@ -45,35 +46,40 @@ func _pprof_show(m *ice.Message, zone string, seconds string) {
m.Richs(PPROF, nil, zone, func(key string, val map[string]interface{}) { m.Richs(PPROF, nil, zone, func(key string, val map[string]interface{}) {
val = val[kit.MDB_META].(map[string]interface{}) val = val[kit.MDB_META].(map[string]interface{})
// 收藏程序
m.Cmd(ice.WEB_FAVOR, favor, "bin", val[BINNARY], m.Cmd(ice.WEB_CACHE, "catch", "bin", val[BINNARY]).Append("data"))
// 性能分析
msg := m.Cmd(ice.WEB_SPIDE, "self", "cache", "GET", kit.Select("/code/pprof/profile", val[SERVICE]), "seconds", kit.Select("5", seconds))
m.Cmd(ice.WEB_FAVOR, favor, "pprof", zone+".pd.gz", msg.Append("data"))
// 结果摘要
ls := strings.Split(m.Cmdx(ice.CLI_SYSTEM, "go", "tool", "pprof", "-text", msg.Append("text")), "\n")
if len(ls) > 20 {
ls = ls[:20]
}
m.Cmd(ice.WEB_FAVOR, favor, "shell", zone, strings.Join(ls, "\n"))
// 结果展示
p := kit.Format("%s:%s", m.Conf(ice.WEB_SHARE, "meta.host"), m.Cmdx("tcp.getport"))
m.Cmd(ice.CLI_DAEMON, "go", "tool", "pprof", "-http="+p, val[BINNARY], msg.Append("text"))
m.Cmd(ice.WEB_FAVOR, favor, "spide", msg.Append("text"), "http://"+p)
m.Echo(p)
return
m.Gos(m.Spawn(), func(msg *ice.Message) { m.Gos(m.Spawn(), func(msg *ice.Message) {
m.Sleep("1s").Grows(PPROF, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { m.Sleep("1s").Grows(PPROF, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) {
// 压测命令 // 压测命令
m.Cmd(ice.WEB_FAVOR, favor, "shell", value[kit.MDB_TEXT], m.Cmdx(kit.Split(kit.Format(value[kit.MDB_TEXT])))) m.Log_EXPORT(kit.MDB_META, PPROF, kit.MDB_ZONE, zone, kit.MDB_VALUE, kit.Format(value))
res := web.FavorShow(m.Spawn(), kit.Format(value[kit.MDB_TYPE]), kit.Format(value[kit.MDB_NAME]), kit.Format(value[kit.MDB_TEXT]), kit.Simple(value[kit.MDB_EXTRA])...).Result()
web.FavorInsert(m, favor, kit.Format(value[kit.MDB_TYPE]), kit.Format(value[kit.MDB_TEXT]), res)
}) })
}) })
})
// 收藏程序
res := web.CacheCatch(m.Spawn(), kit.MIME_FILE, kit.Format(val[BINNARY])).Append(kit.MDB_DATA)
web.FavorInsert(m, favor, kit.MIME_FILE, val[BINNARY], res)
// 性能分析
msg := m.Cmd(ice.WEB_SPIDE, "self", "cache", "GET", kit.Select("/code/pprof/profile", val[SERVICE]), "seconds", kit.Select("5", seconds))
m.Cmd(ice.WEB_FAVOR, favor, PPROF, kit.Keys(zone, "pd.gz"), msg.Append(kit.MDB_DATA))
// 结果摘要
cmd := kit.Simple(m.Confv(PPROF, "meta.pprof"), "-text", val[BINNARY], msg.Append(kit.MDB_TEXT))
ls := strings.Split(m.Cmdx(ice.CLI_SYSTEM, cmd), "\n")
if len(ls) > 20 {
ls = ls[:20]
}
web.FavorInsert(m, favor, kit.MIME_FILE, val[BINNARY], res)
web.FavorInsert(m, favor, ice.TYPE_SHELL, strings.Join(cmd, " "), strings.Join(ls, "\n"))
// 结果展示
p := kit.Format("%s:%s", m.Conf(ice.WEB_SHARE, "meta.host"), m.Cmdx("tcp.getport"))
m.Option(cli.CMD_STDOUT, "var/daemon/stdout")
m.Option(cli.CMD_STDERR, "var/daemon/stderr")
m.Cmd(cli.DAEMON, m.Confv(PPROF, "meta.pprof"), "-http="+p, val[BINNARY], msg.Append(kit.MDB_TEXT))
web.FavorInsert(m, favor, ice.TYPE_SPIDE, msg.Append(kit.MDB_TEXT), "http://"+p+"/ui/top")
m.Echo(p)
})
} }
func _pprof_modify(m *ice.Message, zone, id, pro, set, old string) { func _pprof_modify(m *ice.Message, zone, id, pro, set, old string) {
m.Richs(PPROF, nil, kit.Select(kit.MDB_FOREACH, zone), func(key string, val map[string]interface{}) { m.Richs(PPROF, nil, kit.Select(kit.MDB_FOREACH, zone), func(key string, val map[string]interface{}) {
@ -121,6 +127,7 @@ func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
PPROF: {Name: "pprof", Help: "性能分析", Value: kit.Data(kit.MDB_SHORT, kit.MDB_ZONE, PPROF: {Name: "pprof", Help: "性能分析", Value: kit.Data(kit.MDB_SHORT, kit.MDB_ZONE,
PPROF, []string{"go", "tool", "pprof"},
web.FAVOR, "pprof", web.FAVOR, "pprof",
)}, )},
}, },
@ -130,13 +137,19 @@ func init() {
_pprof_create(m, arg[0], kit.Select("bin/ice.bin", arg, 1), _pprof_create(m, arg[0], kit.Select("bin/ice.bin", arg, 1),
kit.Select("http://localhost:9020/code/pprof/profile", arg, 2), kit.Select("3", arg, 3)) kit.Select("http://localhost:9020/code/pprof/profile", arg, 2), kit.Select("3", arg, 3))
}}, }},
kit.MDB_INSERT: {Name: "insert zone type name text", Help: "插入", Hand: func(m *ice.Message, arg ...string) { kit.MDB_INSERT: {Name: "insert zone type name [text]", Help: "插入", Hand: func(m *ice.Message, arg ...string) {
_pprof_insert(m, arg[0], arg[1], arg[2], kit.Select("http://localhost:9020/code/bench?cmd="+arg[2], arg, 3)) if len(arg) == 2 {
arg = append(arg, "")
}
if len(arg) == 3 {
arg = append(arg, "")
}
_pprof_insert(m, arg[0], arg[1], arg[2], kit.Select("http://localhost:9020/code/bench?cmd="+arg[2], arg, 3), arg[4:]...)
}}, }},
kit.MDB_MODIFY: {Name: "modify key value old", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { kit.MDB_MODIFY: {Name: "modify key value old", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
_pprof_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), arg[0], arg[1], kit.Select("", arg, 2)) _pprof_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), arg[0], arg[1], kit.Select("", arg, 2))
}}, }},
kit.MDB_SHOW: {Name: "show", Help: "运行", Hand: func(m *ice.Message, arg ...string) { kit.MDB_SHOW: {Name: "show type name text arg...", Help: "运行", Hand: func(m *ice.Message, arg ...string) {
_pprof_show(m, m.Option(kit.MDB_ZONE), m.Option(SECONDS)) _pprof_show(m, m.Option(kit.MDB_ZONE), m.Option(SECONDS))
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -34,7 +34,7 @@ func (m *Message) log(level string, str string, arg ...interface{}) *Message {
} }
switch level { switch level {
case LOG_INFO, LOG_WARN: case LOG_INFO, LOG_WARN, "refer", "form":
default: default:
_, file, line, _ := runtime.Caller(2) _, file, line, _ := runtime.Caller(2)
ls := strings.Split(file, "/") ls := strings.Split(file, "/")

View File

@ -27,14 +27,17 @@ var Index = &ice.Context{Name: "zsh", Help: "命令行",
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Conf(ice.WEB_FAVOR, "meta.render.shell", m.AddCmd(&ice.Command{Name: "render favor id", Help: "渲染引擎", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Conf(ice.WEB_FAVOR, "meta.render.shell", m.AddCmd(&ice.Command{Name: "render type name text", Help: "渲染引擎", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
value := m.Optionv("value").(map[string]interface{}) value, _ := m.Optionv(kit.MDB_VALUE).(map[string]interface{})
m.Option("cmd_dir", kit.Value(value, "extra.pwd")) m.Option("cmd_dir", kit.Value(value, "extra.pwd"))
m.Cmdy(ice.CLI_SYSTEM, value["text"]) m.Cmdy(ice.CLI_SYSTEM, kit.Select(kit.Format(value["text"]), arg, 2))
}})) }}))
m.Conf(ice.WEB_FAVOR, "meta.render.cmd", m.AddCmd(&ice.Command{Name: "render favor id", Help: "渲染引擎", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Conf(ice.WEB_FAVOR, "meta.render.cmd", m.AddCmd(&ice.Command{Name: "render type name text", Help: "渲染引擎", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
value := m.Optionv("value").(map[string]interface{}) value, _ := m.Optionv(kit.MDB_VALUE).(map[string]interface{})
m.Cmdy(kit.Split(kit.Format(value["text"]))) m.Cmdy(kit.Split(kit.Format(kit.Select(kit.Format(value["text"], arg, 2)))))
}}))
m.Conf(ice.WEB_FAVOR, "meta.render.bin", m.AddCmd(&ice.Command{Name: "render type name text", Help: "渲染引擎", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmdy(ice.CLI_SYSTEM, "file", arg[2])
}})) }}))
}}, }},
ice.CODE_PREPARE: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.CODE_PREPARE: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {