mirror of
https://shylinux.com/x/icebergs
synced 2025-04-25 17:18:05 +08:00
opt base
This commit is contained in:
parent
a3da6968ca
commit
3a4480bb37
@ -2,6 +2,7 @@ package aaa
|
||||
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
)
|
||||
|
||||
@ -9,27 +10,28 @@ const (
|
||||
ErrNotAuth = "not auth: "
|
||||
)
|
||||
const (
|
||||
USERZONE = "userzone"
|
||||
USERNICK = "usernick"
|
||||
USERNAME = "username"
|
||||
HOSTNAME = "hostname"
|
||||
PASSWORD = "password"
|
||||
IP = "ip"
|
||||
UA = "ua"
|
||||
|
||||
USERROLE = "userrole"
|
||||
USERNODE = "usernode"
|
||||
HOSTPORT = "hostport"
|
||||
USERNAME = "username"
|
||||
PASSWORD = "password"
|
||||
USERNICK = "usernick"
|
||||
USERZONE = "userzone"
|
||||
|
||||
SESSID = "sessid"
|
||||
)
|
||||
const AAA = "aaa"
|
||||
|
||||
var Index = &ice.Context{Name: "aaa", Help: "认证模块", Commands: map[string]*ice.Command{
|
||||
var Index = &ice.Context{Name: AAA, Help: "认证模块", Commands: map[string]*ice.Command{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Rich(ROLE, nil, kit.Dict(kit.MDB_NAME, VOID, White, kit.Dict(), Black, kit.Dict()))
|
||||
m.Rich(ROLE, nil, kit.Dict(kit.MDB_NAME, TECH, Black, kit.Dict(), White, kit.Dict()))
|
||||
m.Load()
|
||||
m.Cmd("mdb.search", "create", "user", "user", "aaa")
|
||||
m.Cmd(mdb.SEARCH, mdb.CREATE, USER, USER, AAA)
|
||||
}},
|
||||
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Save(USER, SESS, ROLE)
|
||||
m.Save()
|
||||
}},
|
||||
}}
|
||||
|
||||
|
5
base/aaa/aaa.shy
Normal file
5
base/aaa/aaa.shy
Normal file
@ -0,0 +1,5 @@
|
||||
chapter "aaa"
|
||||
|
||||
field "用户" user
|
||||
field "会话" sess
|
||||
field "角色" role
|
@ -2,6 +2,7 @@ package aaa
|
||||
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"strings"
|
||||
@ -16,6 +17,9 @@ const ( // 角色操作
|
||||
White = "white"
|
||||
Black = "black"
|
||||
Right = "right"
|
||||
|
||||
WHITE = "white"
|
||||
BLACK = "black"
|
||||
)
|
||||
const ( // 返回结果
|
||||
OK = "ok"
|
||||
@ -103,10 +107,10 @@ const ROLE = "role"
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
ROLE: {Name: "role", Help: "角色", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME)},
|
||||
ROLE: {Name: ROLE, Help: "角色", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME)},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
ROLE: {Name: "role [role [user...]]", Help: "角色", Action: map[string]*ice.Action{
|
||||
ROLE: {Name: "role role auto 添加", Help: "角色", Action: map[string]*ice.Action{
|
||||
White: {Name: "white role chain...", Help: "白名单", Hand: func(m *ice.Message, arg ...string) {
|
||||
_role_white(m, arg[0], strings.ReplaceAll(kit.Keys(arg[1:]), "/", "."), true)
|
||||
}},
|
||||
@ -118,11 +122,27 @@ func init() {
|
||||
m.Echo(OK)
|
||||
}
|
||||
}},
|
||||
mdb.CREATE: {Name: "create zone=white,black role=void@key key=", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Richs(ROLE, nil, m.Option(ROLE), func(key string, value map[string]interface{}) {
|
||||
list := value[m.Option(kit.MDB_ZONE)].(map[string]interface{})
|
||||
m.Log_CREATE(ROLE, m.Option(ROLE), list[m.Option(kit.MDB_KEY)])
|
||||
list[m.Option(kit.MDB_KEY)] = true
|
||||
})
|
||||
}},
|
||||
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Richs(ROLE, nil, m.Option(ROLE), func(key string, value map[string]interface{}) {
|
||||
list := value[m.Option(kit.MDB_ZONE)].(map[string]interface{})
|
||||
m.Log_REMOVE(ROLE, m.Option(ROLE), list[m.Option(kit.MDB_KEY)])
|
||||
delete(list, m.Option(kit.MDB_KEY))
|
||||
})
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) > 1 {
|
||||
_role_user(m, arg[0], arg[1:]...)
|
||||
}
|
||||
|
||||
_role_list(m, kit.Select("", arg, 0))
|
||||
m.PushAction(mdb.REMOVE)
|
||||
}},
|
||||
},
|
||||
}, nil)
|
||||
|
@ -6,14 +6,9 @@ import (
|
||||
kit "github.com/shylinux/toolkits"
|
||||
)
|
||||
|
||||
func _sess_list(m *ice.Message) {
|
||||
m.Richs(SESS, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
|
||||
m.Push(key, value, []string{kit.MDB_TIME, kit.MDB_KEY, USERNAME, USERROLE})
|
||||
})
|
||||
}
|
||||
func _sess_auth(m *ice.Message, sessid string, username string, userrole string) {
|
||||
m.Richs(SESS, nil, sessid, func(value map[string]interface{}) {
|
||||
if m.Option(ice.MSG_USERROLE) == ROOT {
|
||||
if value = kit.GetMeta(value); m.Option(ice.MSG_USERROLE) == ROOT {
|
||||
value[USERROLE] = userrole
|
||||
} else if m.Option(ice.MSG_USERROLE) == TECH && userrole != ROOT {
|
||||
value[USERROLE] = userrole
|
||||
@ -26,7 +21,10 @@ func _sess_auth(m *ice.Message, sessid string, username string, userrole string)
|
||||
}
|
||||
func _sess_check(m *ice.Message, sessid string) {
|
||||
m.Richs(SESS, nil, sessid, func(value map[string]interface{}) {
|
||||
value = kit.GetMeta(value)
|
||||
m.Richs(USER, nil, value[USERNAME], func(value map[string]interface{}) {
|
||||
value = kit.GetMeta(value)
|
||||
|
||||
if m.Option(ice.MSG_USERNICK, value[USERNICK]) == "" {
|
||||
if name := kit.Format(value[USERNAME]); len(name) > 10 {
|
||||
m.Option(ice.MSG_USERNICK, name[:10])
|
||||
@ -46,13 +44,14 @@ func _sess_create(m *ice.Message, username string) string {
|
||||
if m.Richs(USER, nil, username, nil) == nil {
|
||||
_user_create(m, username, "")
|
||||
}
|
||||
h := m.Rich(SESS, nil, kit.Dict(
|
||||
kit.MDB_TIME, m.Time(m.Conf(SESS, "meta.expire")),
|
||||
|
||||
m.Cmdy(mdb.INSERT, SESS, "", mdb.HASH,
|
||||
USERNAME, username, "from", m.Option(ice.MSG_SESSID),
|
||||
))
|
||||
m.Log_CREATE(SESSID, h, USERNAME, username)
|
||||
m.Echo(h)
|
||||
return h
|
||||
kit.MDB_TIME, m.Time(m.Conf(SESS, "meta.expire")),
|
||||
"agent", m.Option(ice.MSG_USERUA),
|
||||
"ip", m.Option(ice.MSG_USERIP),
|
||||
)
|
||||
return m.Result()
|
||||
}
|
||||
|
||||
func SessCheck(m *ice.Message, sessid string) *ice.Message {
|
||||
@ -69,22 +68,27 @@ const SESS = "sess"
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
SESS: {Name: "sess", Help: "会话", Value: kit.Data(
|
||||
SESS: {Name: SESS, Help: "会话", Value: kit.Data(
|
||||
kit.MDB_SHORT, "uniq", "expire", "720h",
|
||||
)},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
SESS: {Name: "sess", Help: "会话", Action: map[string]*ice.Action{
|
||||
mdb.CREATE: {Name: "create [username]", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
|
||||
_sess_create(m, kit.Select("", arg, 0))
|
||||
SESS: {Name: "sess hash auto", Help: "会话", Action: map[string]*ice.Action{
|
||||
"auth": {Name: "auth sessid username [userrole]", Help: "授权", Hand: func(m *ice.Message, arg ...string) {
|
||||
_sess_auth(m, arg[0], arg[1], kit.Select("", arg, 2))
|
||||
}},
|
||||
"check": {Name: "check sessid", Help: "校验", Hand: func(m *ice.Message, arg ...string) {
|
||||
_sess_check(m, arg[0])
|
||||
}},
|
||||
"auth": {Name: "auth sessid username [userrole]", Help: "授权", Hand: func(m *ice.Message, arg ...string) {
|
||||
_sess_auth(m, arg[0], arg[1], kit.Select("", arg, 2))
|
||||
|
||||
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(mdb.DELETE, SESS, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { _sess_list(m) }},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Option(mdb.FIELDS, kit.Select("time,hash,username,userrole", mdb.DETAIL, len(arg) > 0))
|
||||
m.Cmdy(mdb.SELECT, SESS, "", mdb.HASH, kit.MDB_HASH, arg)
|
||||
m.PushAction(mdb.REMOVE)
|
||||
}},
|
||||
},
|
||||
}, nil)
|
||||
}
|
||||
|
@ -2,23 +2,12 @@ package aaa
|
||||
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/cli"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
USER_CREATE = "user.create"
|
||||
)
|
||||
|
||||
func _user_list(m *ice.Message) {
|
||||
m.Richs(USER, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
|
||||
m.Push(key, value, []string{kit.MDB_TIME, USERZONE, USERNICK, USERNAME})
|
||||
})
|
||||
m.Sort(USERNAME)
|
||||
}
|
||||
func _user_login(m *ice.Message, name, word string) (ok bool) {
|
||||
if m.Richs(USER, nil, name, nil) == nil {
|
||||
_user_create(m, name, "")
|
||||
@ -33,24 +22,10 @@ func _user_login(m *ice.Message, name, word string) (ok bool) {
|
||||
})
|
||||
return ok
|
||||
}
|
||||
func _user_modify(m *ice.Message, name string, arg ...string) {
|
||||
if m.Richs(USER, nil, name, nil) == nil {
|
||||
_user_create(m, name, "")
|
||||
}
|
||||
|
||||
m.Log_MODIFY(USERNAME, name, arg)
|
||||
m.Richs(USER, nil, name, func(key string, value map[string]interface{}) {
|
||||
for i := 0; i < len(arg)-1; i += 2 {
|
||||
kit.Value(value, arg[i], arg[i+1])
|
||||
}
|
||||
})
|
||||
}
|
||||
func _user_create(m *ice.Message, name, word string) {
|
||||
h := m.Rich(USER, nil, kit.Dict(
|
||||
USERNAME, name, PASSWORD, word,
|
||||
USERNICK, name, USERNODE, cli.NodeName,
|
||||
USERZONE, m.Option(ice.MSG_USERZONE),
|
||||
USERNODE, cli.NodeName,
|
||||
USERNICK, name, USERZONE, m.Option(ice.MSG_USERZONE),
|
||||
))
|
||||
m.Log_CREATE(USERNAME, name, "hash", h)
|
||||
m.Event(USER_CREATE, name)
|
||||
@ -72,27 +47,30 @@ func _user_search(m *ice.Message, kind, name, text string, arg ...string) {
|
||||
}
|
||||
|
||||
func UserRoot(m *ice.Message) {
|
||||
cli.PassWord = kit.Hashs("uniq")
|
||||
cli.PassWord = cli.UserName
|
||||
_user_create(m, cli.UserName, cli.PassWord)
|
||||
ice.Info.PassWord = kit.Hashs("uniq")
|
||||
ice.Info.PassWord = ice.Info.UserName
|
||||
_user_create(m, ice.Info.UserName, ice.Info.PassWord)
|
||||
}
|
||||
func UserNick(m *ice.Message, username interface{}) (nick string) {
|
||||
m.Richs(USER, nil, kit.Format(username), func(key string, value map[string]interface{}) {
|
||||
value = kit.GetMeta(value)
|
||||
nick = kit.Format(value[USERNICK])
|
||||
})
|
||||
return
|
||||
}
|
||||
func UserZone(m *ice.Message, username interface{}) (zone string) {
|
||||
m.Richs(USER, nil, kit.Format(username), func(key string, value map[string]interface{}) {
|
||||
value = kit.GetMeta(value)
|
||||
zone = kit.Format(value[USERZONE])
|
||||
})
|
||||
return
|
||||
}
|
||||
func UserRole(m *ice.Message, username interface{}) (role string) {
|
||||
if role = VOID; username == cli.UserName {
|
||||
if role = VOID; username == ice.Info.UserName {
|
||||
return ROOT
|
||||
}
|
||||
m.Richs(ROLE, nil, TECH, func(key string, value map[string]interface{}) {
|
||||
value = kit.GetMeta(value)
|
||||
if kit.Value(value, kit.Keys(USER, username)) == true {
|
||||
role = TECH
|
||||
}
|
||||
@ -109,28 +87,33 @@ func UserLogin(m *ice.Message, username, password string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
const (
|
||||
USER_CREATE = "user.create"
|
||||
)
|
||||
|
||||
const USER = "user"
|
||||
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
USER: {Name: "user", Help: "用户", Value: kit.Data(kit.MDB_SHORT, USERNAME)},
|
||||
USER: {Name: USER, Help: "用户", Value: kit.Data(kit.MDB_SHORT, USERNAME)},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
USER: {Name: "user", Help: "用户", Action: map[string]*ice.Action{
|
||||
mdb.CREATE: {Name: "create username [password]", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
|
||||
_user_create(m, arg[0], kit.Select("", arg, 1))
|
||||
USER: {Name: "user username auto", Help: "用户", Action: map[string]*ice.Action{
|
||||
mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(mdb.MODIFY, USER, "", mdb.HASH, USERNAME, m.Option(USERNAME), arg)
|
||||
}},
|
||||
mdb.MODIFY: {Name: "modify [key value]...", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
|
||||
_user_modify(m, m.Option(USERNAME), arg...)
|
||||
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(mdb.REMOVE, USER, "", mdb.HASH, USERNAME, m.Option(USERNAME))
|
||||
}},
|
||||
mdb.SEARCH: {Name: "search type name text arg...", Help: "搜索", Hand: func(m *ice.Message, arg ...string) {
|
||||
_user_search(m, arg[0], arg[1], kit.Select("", arg, 2))
|
||||
}},
|
||||
"login": {Name: "login username password", Help: "登录", Hand: func(m *ice.Message, arg ...string) {
|
||||
_user_login(m, arg[0], arg[1])
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { _user_list(m) }},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Option(mdb.FIELDS, kit.Select("time,userzone,usernick,username", mdb.DETAIL, len(arg) > 0))
|
||||
m.Cmdy(mdb.SELECT, USER, "", mdb.HASH, USERNAME, arg)
|
||||
m.PushAction(mdb.REMOVE)
|
||||
}},
|
||||
},
|
||||
}, nil)
|
||||
}
|
||||
|
117
base/cli/cli.go
117
base/cli/cli.go
@ -2,12 +2,8 @@ package cli
|
||||
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/ctx"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/user"
|
||||
"path"
|
||||
@ -15,27 +11,15 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var UserName = ""
|
||||
var PassWord = ""
|
||||
var HostName = ""
|
||||
var PathName = ""
|
||||
var NodeName = ""
|
||||
var NodeType = ""
|
||||
|
||||
func NodeInfo(m *ice.Message, kind, name string) {
|
||||
name = strings.ReplaceAll(name, ".", "_")
|
||||
m.Conf(RUNTIME, "node.type", kind)
|
||||
m.Conf(RUNTIME, "node.name", name)
|
||||
NodeName = name
|
||||
NodeType = kind
|
||||
ice.Info.NodeName = name
|
||||
ice.Info.NodeType = kind
|
||||
}
|
||||
|
||||
const RUNTIME = "runtime"
|
||||
|
||||
var Index = &ice.Context{Name: "cli", Help: "命令模块",
|
||||
Configs: map[string]*ice.Config{
|
||||
RUNTIME: {Name: "runtime", Help: "运行环境", Value: kit.Dict()},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Load()
|
||||
@ -46,7 +30,6 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
|
||||
m.Conf(RUNTIME, "conf.ctx_shy", os.Getenv("ctx_shy"))
|
||||
m.Conf(RUNTIME, "conf.ctx_pid", os.Getenv("ctx_pid"))
|
||||
m.Conf(RUNTIME, "conf.ctx_user", os.Getenv("ctx_user"))
|
||||
m.Conf(RUNTIME, "conf.ctx_pod", os.Getenv("ctx_pod"))
|
||||
|
||||
// 主机信息
|
||||
m.Conf(RUNTIME, "host.GOARCH", runtime.GOARCH)
|
||||
@ -54,11 +37,6 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
|
||||
m.Conf(RUNTIME, "host.pid", os.Getpid())
|
||||
|
||||
// 启动信息
|
||||
if m.Conf(RUNTIME, "boot.username", kit.Select(os.Getenv("USER"), os.Getenv("ctx_user"))) == "" {
|
||||
if user, e := user.Current(); e == nil && user.Name != "" {
|
||||
m.Conf(RUNTIME, "boot.username", kit.Select(user.Name, os.Getenv("ctx_user")))
|
||||
}
|
||||
}
|
||||
if name, e := os.Hostname(); e == nil {
|
||||
m.Conf(RUNTIME, "boot.hostname", kit.Select(name, os.Getenv("HOSTNAME")))
|
||||
}
|
||||
@ -70,9 +48,14 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
|
||||
name = ls[len(ls)-1]
|
||||
m.Conf(RUNTIME, "boot.pathname", name)
|
||||
}
|
||||
UserName = m.Conf(RUNTIME, "boot.username")
|
||||
HostName = m.Conf(RUNTIME, "boot.hostname")
|
||||
PathName = m.Conf(RUNTIME, "boot.pathname")
|
||||
if m.Conf(RUNTIME, "boot.username", kit.Select(os.Getenv("USER"), os.Getenv("ctx_user"))) == "" {
|
||||
if user, e := user.Current(); e == nil && user.Name != "" {
|
||||
m.Conf(RUNTIME, "boot.username", kit.Select(user.Name, os.Getenv("ctx_user")))
|
||||
}
|
||||
}
|
||||
ice.Info.HostName = m.Conf(RUNTIME, "boot.hostname")
|
||||
ice.Info.PathName = m.Conf(RUNTIME, "boot.pathname")
|
||||
ice.Info.UserName = m.Conf(RUNTIME, "boot.username")
|
||||
|
||||
// 启动记录
|
||||
count := kit.Int(m.Conf(RUNTIME, "boot.count")) + 1
|
||||
@ -83,84 +66,20 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
|
||||
NodeInfo(m, "worker", m.Conf(RUNTIME, "boot.pathname"))
|
||||
m.Info("runtime %v", kit.Formats(m.Confv(RUNTIME)))
|
||||
|
||||
n := kit.Int(kit.Select("20", m.Conf(RUNTIME, "host.GOMAXPROCS")))
|
||||
n := kit.Int(kit.Select("1", m.Conf(RUNTIME, "host.GOMAXPROCS")))
|
||||
m.Logs("host", "gomaxprocs", n)
|
||||
runtime.GOMAXPROCS(n)
|
||||
|
||||
m.Cmdy(mdb.ENGINE, mdb.CREATE, "shell", m.AddCmd(&ice.Command{Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmdy(SYSTEM, arg[2])
|
||||
}}))
|
||||
// 版本信息
|
||||
m.Conf(RUNTIME, "build.time", ice.Info.Build.Time)
|
||||
m.Conf(RUNTIME, "build.version", ice.Info.Build.Version)
|
||||
m.Conf(RUNTIME, "build.hostname", ice.Info.Build.HostName)
|
||||
m.Conf(RUNTIME, "build.username", ice.Info.Build.UserName)
|
||||
}},
|
||||
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Save(RUNTIME, SYSTEM, DAEMON)
|
||||
}},
|
||||
|
||||
"proc": {Name: "proc name=auto PID=auto auto", Help: "进程管理", Action: map[string]*ice.Action{
|
||||
"kill": {Name: "kill", Help: "结束", Hand: func(m *ice.Message, arg ...string) {
|
||||
if p, e := os.FindProcess(kit.Int(m.Option("PID"))); m.Assert(e) {
|
||||
m.Assert(p.Kill())
|
||||
}
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
msg := m.Spawn()
|
||||
msg.Split(m.Cmdx(SYSTEM, "ps", "ux"), "", " ", "\n")
|
||||
msg.Table(func(index int, value map[string]string, head []string) {
|
||||
if m.Appendv(ice.MSG_APPEND, "action", head); len(arg) == 2 && value["PID"] == arg[1] {
|
||||
m.PushRender("action", "button", "结束")
|
||||
m.Push("", value)
|
||||
return
|
||||
}
|
||||
if len(arg) == 0 || len(arg) == 1 && strings.Contains(value["COMMAND"], arg[0]) {
|
||||
m.PushRender("action", "button", "结束")
|
||||
m.Push("", value)
|
||||
}
|
||||
})
|
||||
}},
|
||||
RUNTIME: {Name: "runtime name auto", Help: "运行环境", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
switch kit.Select("", arg, 0) {
|
||||
case "procinfo":
|
||||
m.Split(m.Cmdx(SYSTEM, "ps", "u"), "", " ", "\n")
|
||||
|
||||
case "hostinfo":
|
||||
if f, e := os.Open("/proc/cpuinfo"); e == nil {
|
||||
defer f.Close()
|
||||
if b, e := ioutil.ReadAll(f); e == nil {
|
||||
m.Push("nCPU", bytes.Count(b, []byte("processor")))
|
||||
}
|
||||
}
|
||||
if f, e := os.Open("/proc/meminfo"); e == nil {
|
||||
defer f.Close()
|
||||
if b, e := ioutil.ReadAll(f); e == nil {
|
||||
for i, ls := range strings.Split(string(b), "\n") {
|
||||
vs := kit.Split(ls, ": ")
|
||||
m.Push(strings.TrimSpace(vs[0]), kit.FmtSize(kit.Int64(strings.TrimSpace(vs[1]))*1024))
|
||||
if i > 1 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m.Push("uptime", kit.Split(m.Cmdx(SYSTEM, "uptime"), ",")[0])
|
||||
case "diskinfo":
|
||||
m.Spawn().Split(m.Cmdx(SYSTEM, "df", "-h"), "", " ", "\n").Table(func(index int, value map[string]string, head []string) {
|
||||
if strings.HasPrefix(value["Filesystem"], "/dev") {
|
||||
m.Push("", value, head)
|
||||
}
|
||||
})
|
||||
case "ifconfig":
|
||||
m.Cmdy("tcp.host")
|
||||
case "userinfo":
|
||||
m.Split(m.Cmdx(SYSTEM, "who"), "user term time", " ", "\n")
|
||||
|
||||
case "hostname":
|
||||
m.Conf(RUNTIME, "boot.hostname", arg[1])
|
||||
HostName = arg[1]
|
||||
m.Echo(HostName)
|
||||
default:
|
||||
m.Cmdy(ctx.CONFIG, RUNTIME, arg)
|
||||
}
|
||||
m.Save()
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
func init() { ice.Index.Register(Index, nil, RUNTIME, SYSTEM, DAEMON, PYTHON) }
|
||||
func init() { ice.Index.Register(Index, nil, RUNTIME, SYSTEM, DAEMON, PYTHON, OUTPUT) }
|
||||
|
9
base/cli/cli.shy
Normal file
9
base/cli/cli.shy
Normal file
@ -0,0 +1,9 @@
|
||||
chapter "cli"
|
||||
|
||||
field "命令" system
|
||||
field "输出" output
|
||||
field "守护" daemon
|
||||
field "脚本" python
|
||||
|
||||
field "环境" runtime
|
||||
field "进程" cli.proc
|
@ -2,6 +2,8 @@ package cli
|
||||
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/aaa"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"fmt"
|
||||
@ -10,15 +12,6 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
ErrStart = "daemon start: "
|
||||
)
|
||||
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)
|
||||
@ -35,30 +28,40 @@ func _daemon_show(m *ice.Message, cmd *exec.Cmd, out, err string) {
|
||||
return
|
||||
}
|
||||
|
||||
h := m.Rich(DAEMON, nil, kit.Dict(
|
||||
kit.MDB_TYPE, "shell", kit.MDB_NAME, strings.Join(cmd.Args, " "),
|
||||
kit.SSH_DIR, cmd.Dir, kit.SSH_PID, cmd.Process.Pid, kit.MDB_STATUS, StatusStart,
|
||||
kit.MDB_EXTRA, kit.Dict(CMD_STDOUT, out, CMD_STDERR, err),
|
||||
))
|
||||
m.Log_EXPORT(kit.MDB_META, DAEMON, kit.MDB_KEY, h, kit.SSH_PID, cmd.Process.Pid)
|
||||
h := m.Cmdx(mdb.INSERT, DAEMON, "", mdb.HASH,
|
||||
kit.MDB_STATUS, Status.Start, kit.SSH_CMD, strings.Join(cmd.Args, " "),
|
||||
kit.SSH_DIR, cmd.Dir, kit.SSH_ENV, cmd.Env, kit.SSH_PID, cmd.Process.Pid,
|
||||
CMD_STDOUT, out, CMD_STDERR, err,
|
||||
aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERROLE, m.Option(ice.MSG_USERROLE),
|
||||
aaa.IP, m.Option(ice.MSG_USERIP), aaa.UA, m.Option(ice.MSG_USERUA),
|
||||
)
|
||||
m.Echo("%d", cmd.Process.Pid)
|
||||
|
||||
m.Gos(m, func(m *ice.Message) {
|
||||
if e := cmd.Wait(); e != nil {
|
||||
m.Warn(e != nil, ErrStart, cmd.Args, " ", e)
|
||||
m.Richs(DAEMON, nil, h, func(key string, value map[string]interface{}) {
|
||||
kit.Value(value, kit.MDB_STATUS, StatusError)
|
||||
kit.Value(value, kit.Keys(kit.MDB_EXTRA, kit.MDB_ERROR), e)
|
||||
})
|
||||
m.Go(func() {
|
||||
if e := cmd.Wait(); m.Warn(e != nil, ErrStart, cmd.Args, " ", e) {
|
||||
m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, h,
|
||||
kit.MDB_STATUS, Status.Error, kit.MDB_ERROR, e)
|
||||
} else {
|
||||
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.MDB_STATUS, StatusClose)
|
||||
})
|
||||
m.Cost("args", cmd.Args, "code", cmd.ProcessState.ExitCode())
|
||||
m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, h,
|
||||
kit.MDB_STATUS, Status.Stop)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const ErrStart = "daemon start: "
|
||||
|
||||
var Status = struct{ Error, Start, Stop string }{
|
||||
Error: "error",
|
||||
Start: "start",
|
||||
Stop: "stop",
|
||||
}
|
||||
|
||||
const (
|
||||
START = "start"
|
||||
STOP = "stop"
|
||||
)
|
||||
|
||||
const DAEMON = "daemon"
|
||||
|
||||
func init() {
|
||||
@ -67,40 +70,45 @@ func init() {
|
||||
DAEMON: {Name: DAEMON, Help: "守护进程", Value: kit.Data(kit.MDB_PATH, "var/daemon")},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
DAEMON: {Name: "daemon hash 查看:button=auto 清理:button", Help: "守护进程", Action: map[string]*ice.Action{
|
||||
"delete": {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Richs(DAEMON, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {
|
||||
m.Conf(DAEMON, kit.Keys(kit.MDB_HASH, key), "")
|
||||
m.Log_DELETE(DAEMON, kit.Format(value))
|
||||
})
|
||||
DAEMON: {Name: "daemon hash auto 添加 清理", Help: "守护进程", Action: map[string]*ice.Action{
|
||||
START: {Name: "start cmd env dir", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Option(CMD_TYPE, DAEMON)
|
||||
m.Cmdy(SYSTEM, kit.Split(m.Option("cmd")))
|
||||
}},
|
||||
"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 value["status"] == "error" || strings.Count(m.Cmdx(SYSTEM, "ps", value[kit.SSH_PID]), "\n") == 1 {
|
||||
m.Conf(DAEMON, kit.Keys(kit.MDB_HASH, key), "")
|
||||
m.Log_DELETE(DAEMON, kit.Format(value))
|
||||
}
|
||||
})
|
||||
}},
|
||||
"stop": {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Richs(DAEMON, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {
|
||||
STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(mdb.SELECT, DAEMON, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)).Table(func(index int, value map[string]string, head []string) {
|
||||
m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH), kit.MDB_STATUS, Status.Stop)
|
||||
m.Cmdy(SYSTEM, "kill", "-9", value[kit.SSH_PID])
|
||||
if strings.Count(m.Cmdx(SYSTEM, "ps", value[kit.SSH_PID]), "\n") == 1 {
|
||||
value[kit.MDB_STATUS] = StatusClose
|
||||
}
|
||||
})
|
||||
}},
|
||||
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(mdb.DELETE, DAEMON, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
||||
}},
|
||||
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(mdb.PRUNES, DAEMON, "", mdb.HASH, kit.MDB_STATUS, Status.Error)
|
||||
m.Cmdy(mdb.PRUNES, DAEMON, "", mdb.HASH, kit.MDB_STATUS, Status.Stop)
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
m.Option("fields", "time,hash,status,pid,name,dir")
|
||||
m.Cmdy("mdb.select", DAEMON, "", kit.MDB_HASH)
|
||||
m.Sort("time", "time_r")
|
||||
m.PushAction("停止", "删除")
|
||||
return
|
||||
}
|
||||
m.Option(mdb.FIELDS, "time,hash,status,pid,cmd,dir")
|
||||
m.Cmdy(mdb.SELECT, DAEMON, "", mdb.HASH)
|
||||
m.Table(func(index int, value map[string]string, head []string) {
|
||||
switch value[kit.MDB_STATUS] {
|
||||
case Status.Start:
|
||||
m.PushButton(STOP)
|
||||
default:
|
||||
m.PushButton(mdb.REMOVE)
|
||||
}
|
||||
})
|
||||
|
||||
m.Option(CMD_TYPE, DAEMON)
|
||||
m.Cmdy(SYSTEM, arg)
|
||||
} else if m.Richs(DAEMON, "", arg[0], nil) != nil {
|
||||
m.Option(mdb.FIELDS, mdb.DETAIL)
|
||||
m.Cmdy(mdb.SELECT, DAEMON, "", mdb.HASH, kit.MDB_HASH, arg)
|
||||
|
||||
} else {
|
||||
m.Option(CMD_TYPE, DAEMON)
|
||||
m.Cmdy(SYSTEM, arg)
|
||||
}
|
||||
}},
|
||||
},
|
||||
}, nil)
|
||||
|
63
base/cli/output.go
Normal file
63
base/cli/output.go
Normal file
@ -0,0 +1,63 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"io"
|
||||
)
|
||||
|
||||
const OUTPUT = "output"
|
||||
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
OUTPUT: {Name: OUTPUT, Help: "输出", Value: kit.Data()},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
OUTPUT: {Name: "output hash id auto", Help: "输出", Action: map[string]*ice.Action{
|
||||
mdb.CREATE: {Name: "create cmd", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
|
||||
h := m.Cmdx(mdb.INSERT, OUTPUT, "", mdb.HASH, kit.MDB_STATUS, Status.Start, arg)
|
||||
r, w := io.Pipe()
|
||||
m.Go(func() {
|
||||
buf := make([]byte, 1024)
|
||||
for {
|
||||
if n, e := r.Read(buf); e != nil || n == 0 {
|
||||
break
|
||||
} else {
|
||||
m.Grow(OUTPUT, kit.Keys(kit.MDB_HASH, h), kit.Dict(
|
||||
kit.SSH_RES, string(buf[:n]),
|
||||
))
|
||||
}
|
||||
}
|
||||
m.Cmd(mdb.MODIFY, OUTPUT, "", mdb.HASH, kit.MDB_HASH, h, kit.MDB_STATUS, Status.Stop)
|
||||
})
|
||||
m.Option(OUTPUT, w)
|
||||
m.Echo(h)
|
||||
}},
|
||||
mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(mdb.MODIFY, OUTPUT, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH), arg)
|
||||
}},
|
||||
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(mdb.DELETE, OUTPUT, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
||||
}},
|
||||
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(mdb.PRUNES, OUTPUT, "", mdb.HASH, kit.MDB_STATUS, Status.Stop)
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
m.Option(mdb.FIELDS, "time,hash,status,name")
|
||||
m.Cmdy(mdb.SELECT, OUTPUT, "", mdb.HASH)
|
||||
m.PushAction(mdb.REMOVE)
|
||||
return
|
||||
}
|
||||
|
||||
m.Option("_control", "_page")
|
||||
m.Option(mdb.FIELDS, kit.Select("time,id,res", mdb.DETAIL, len(arg) > 1))
|
||||
m.Cmdy(mdb.SELECT, OUTPUT, kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:])
|
||||
m.Sort(kit.MDB_ID)
|
||||
}},
|
||||
},
|
||||
}, nil)
|
||||
}
|
37
base/cli/proc.go
Normal file
37
base/cli/proc.go
Normal file
@ -0,0 +1,37 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{},
|
||||
Commands: map[string]*ice.Command{
|
||||
"proc": {Name: "proc name=ice.bin PID auto", Help: "进程管理", Action: map[string]*ice.Action{
|
||||
"kill": {Name: "kill", Help: "结束", Hand: func(m *ice.Message, arg ...string) {
|
||||
if p, e := os.FindProcess(kit.Int(m.Option("PID"))); m.Assert(e) {
|
||||
m.Assert(p.Kill())
|
||||
}
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
msg := m.Spawn()
|
||||
msg.Split(m.Cmdx(SYSTEM, "ps", "ux"), "", " ", "\n")
|
||||
msg.Table(func(index int, value map[string]string, head []string) {
|
||||
if m.Appendv(ice.MSG_APPEND, "action", head); len(arg) > 1 && value["PID"] != arg[1] {
|
||||
return
|
||||
}
|
||||
if len(arg) > 0 && !strings.Contains(value["COMMAND"], arg[0]) {
|
||||
return
|
||||
}
|
||||
m.PushButton("结束")
|
||||
m.Push("", value)
|
||||
})
|
||||
}},
|
||||
},
|
||||
}, nil)
|
||||
}
|
@ -1,12 +1,10 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
ice "github.com/shylinux/icebergs"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"path"
|
||||
)
|
||||
|
||||
const PYTHON = "python"
|
||||
@ -15,38 +13,35 @@ func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
PYTHON: {Name: "python", Help: "脚本命令", Value: kit.Data(
|
||||
"windows", "http://mirrors.sohu.com/python/3.5.2/Python-3.5.2.tar.xz",
|
||||
"darwin", "http://mirrors.sohu.com/python/3.5.2/Python-3.5.2.tar.xz",
|
||||
"linux", "http://mirrors.sohu.com/python/3.5.2/Python-3.5.2.tar.xz",
|
||||
|
||||
"source", "http://mirrors.sohu.com/python/3.5.2/Python-3.5.2.tar.xz",
|
||||
"qrcode", `import pyqrcode; print(pyqrcode.create('%s').terminal(module_color='%s', quiet_zone=1))`,
|
||||
PYTHON, "python", "pip", "pip",
|
||||
)},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
PYTHON: {Name: "python 编译:button 下载:button", Help: "脚本命令", Action: map[string]*ice.Action{
|
||||
PYTHON: {Name: "python port path auto 启动:button 构建 下载", Help: "脚本命令", Action: map[string]*ice.Action{
|
||||
"download": {Name: "download", Help: "下载", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy("web.code.install", "download", m.Conf(PYTHON, kit.Keys(kit.MDB_META, runtime.GOOS)))
|
||||
m.Cmdy("web.code.install", "download", m.Conf(PYTHON, "meta.source"))
|
||||
}},
|
||||
"compile": {Name: "compile", Help: "编译", Hand: func(m *ice.Message, arg ...string) {
|
||||
name := path.Base(strings.TrimSuffix(strings.TrimSuffix(m.Conf(PYTHON, kit.Keys(kit.MDB_META, runtime.GOOS)), ".tar.xz"), "zip"))
|
||||
m.Option(CMD_DIR, path.Join(m.Conf("web.code.install", kit.META_PATH), name))
|
||||
m.Cmdy(SYSTEM, "./configure", "--prefix="+kit.Path("usr/local"))
|
||||
m.Cmdy(SYSTEM, "make", "-j8")
|
||||
m.Cmdy(SYSTEM, "make", "install")
|
||||
"build": {Name: "build", Help: "构建", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy("web.code.install", "build", m.Conf(PYTHON, "meta.source"))
|
||||
}},
|
||||
"start": {Name: "start", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy("web.code.install", "start", m.Conf(PYTHON, "meta.source"), "bin/python3")
|
||||
}},
|
||||
|
||||
"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", kit.Format(m.Conf(PYTHON, "meta.qrcode"),
|
||||
kit.Select("hello world", arg, 0), kit.Select("blue", arg, 1)))
|
||||
}},
|
||||
"pip": {Name: "pip", Help: "安装", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(SYSTEM, m.Conf(PYTHON, "meta.pip"), "install", arg)
|
||||
}},
|
||||
"run": {Name: "run", Help: "运行", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(SYSTEM, m.Conf(PYTHON, "meta.python"), arg)
|
||||
}},
|
||||
}, 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)
|
||||
m.Cmdy("web.code.install", path.Base(m.Conf(PYTHON, kit.META_SOURCE)), arg)
|
||||
}},
|
||||
},
|
||||
}, nil)
|
||||
|
73
base/cli/runtime.go
Normal file
73
base/cli/runtime.go
Normal file
@ -0,0 +1,73 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/ctx"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const RUNTIME = "runtime"
|
||||
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
RUNTIME: {Name: RUNTIME, Help: "运行环境", Value: kit.Dict()},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
RUNTIME: {Name: "runtime info=procinfo,hostinfo,diskinfo,ifconfig,hostname,userinfo,bootinfo auto", Help: "运行环境", Action: map[string]*ice.Action{
|
||||
"procinfo": {Name: "procinfo", Help: "procinfo", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Split(m.Cmdx(SYSTEM, "ps", "u"), "", " ", "\n")
|
||||
}},
|
||||
"hostinfo": {Name: "hostinfo", Help: "hostinfo", Hand: func(m *ice.Message, arg ...string) {
|
||||
if f, e := os.Open("/proc/cpuinfo"); e == nil {
|
||||
defer f.Close()
|
||||
if b, e := ioutil.ReadAll(f); e == nil {
|
||||
m.Push("nCPU", bytes.Count(b, []byte("processor")))
|
||||
}
|
||||
}
|
||||
if f, e := os.Open("/proc/meminfo"); e == nil {
|
||||
defer f.Close()
|
||||
if b, e := ioutil.ReadAll(f); e == nil {
|
||||
for i, ls := range strings.Split(string(b), "\n") {
|
||||
vs := kit.Split(ls, ": ")
|
||||
m.Push(strings.TrimSpace(vs[0]), kit.FmtSize(kit.Int64(strings.TrimSpace(vs[1]))*1024))
|
||||
if i > 1 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m.Push("uptime", kit.Split(m.Cmdx(SYSTEM, "uptime"), ",")[0])
|
||||
}},
|
||||
"diskinfo": {Name: "diskinfo", Help: "diskinfo", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Spawn().Split(m.Cmdx(SYSTEM, "df", "-h"), "", " ", "\n").Table(func(index int, value map[string]string, head []string) {
|
||||
if strings.HasPrefix(value["Filesystem"], "/dev") {
|
||||
m.Push("", value, head)
|
||||
}
|
||||
})
|
||||
}},
|
||||
"ifconfig": {Name: "ifconfig", Help: "ifconfig", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy("tcp.host")
|
||||
}},
|
||||
"hostname": {Name: "hostname", Help: "hostname", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Conf(RUNTIME, "boot.hostname", arg[1])
|
||||
ice.Info.HostName = arg[1]
|
||||
m.Echo(ice.Info.HostName)
|
||||
}},
|
||||
"userinfo": {Name: "userinfo", Help: "userinfo", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Split(m.Cmdx(SYSTEM, "who"), "user term time", " ", "\n")
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) > 0 && arg[0] == "bootinfo" {
|
||||
arg = arg[1:]
|
||||
}
|
||||
m.Cmdy(ctx.CONFIG, RUNTIME, arg)
|
||||
}},
|
||||
},
|
||||
}, nil)
|
||||
}
|
@ -2,19 +2,60 @@ package cli
|
||||
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/aaa"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func _system_show(m *ice.Message, cmd *exec.Cmd) {
|
||||
m.Cmd(mdb.INSERT, SYSTEM, "", mdb.LIST, "cmd", strings.Join(cmd.Args, " "), "dir", cmd.Dir, "env", strings.Join(cmd.Env, ","),
|
||||
aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERROLE, m.Option(ice.MSG_USERROLE),
|
||||
aaa.IP, m.Option(ice.MSG_USERIP), aaa.UA, m.Option(ice.MSG_USERUA),
|
||||
)
|
||||
|
||||
if w, ok := m.Optionv("output").(io.WriteCloser); ok {
|
||||
cmd.Stderr = w
|
||||
cmd.Stdout = w
|
||||
|
||||
if e := cmd.Run(); e != nil {
|
||||
m.Warn(e != nil, ErrRun, strings.Join(cmd.Args, " "), "\n", e.Error())
|
||||
} else {
|
||||
m.Cost("args", cmd.Args, "code", cmd.ProcessState.ExitCode())
|
||||
}
|
||||
} else {
|
||||
err := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||
out := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||
cmd.Stderr = err
|
||||
cmd.Stdout = out
|
||||
defer func() {
|
||||
m.Push(CMD_ERR, err.String())
|
||||
m.Push(CMD_OUT, out.String())
|
||||
m.Echo(kit.Select(err.String(), out.String()))
|
||||
}()
|
||||
|
||||
if e := cmd.Run(); e != nil {
|
||||
m.Warn(e != nil, ErrRun, strings.Join(cmd.Args, " "), "\n", kit.Select(e.Error(), err.String()))
|
||||
} else {
|
||||
m.Cost("args", cmd.Args, "code", cmd.ProcessState.ExitCode(), "err", err.Len(), "out", out.Len())
|
||||
}
|
||||
}
|
||||
|
||||
m.Push(kit.MDB_TIME, m.Time())
|
||||
m.Push(CMD_CODE, int(cmd.ProcessState.ExitCode()))
|
||||
}
|
||||
|
||||
const ErrRun = "cli run err: "
|
||||
|
||||
const (
|
||||
CMD_STDOUT = "cmd_stdout"
|
||||
CMD_STDERR = "cmd_stderr"
|
||||
CMD_STDOUT = "cmd_stdout"
|
||||
|
||||
CMD_TYPE = "cmd_type"
|
||||
CMD_DIR = "cmd_dir"
|
||||
@ -25,38 +66,25 @@ const (
|
||||
CMD_CODE = "cmd_code"
|
||||
)
|
||||
|
||||
const ErrRun = "run err "
|
||||
|
||||
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
|
||||
defer func() {
|
||||
m.Cost("%v exit: %v out: %v err: %v ",
|
||||
cmd.Args, cmd.ProcessState.ExitCode(), out.Len(), err.Len())
|
||||
}()
|
||||
|
||||
if e := cmd.Run(); e != nil {
|
||||
m.Warn(e != nil, ErrRun, strings.Join(cmd.Args, " "), "\n", kit.Select(e.Error(), err.String()))
|
||||
}
|
||||
|
||||
m.Push(kit.MDB_TIME, m.Time())
|
||||
m.Push(CMD_CODE, int(cmd.ProcessState.ExitCode()))
|
||||
m.Push(CMD_ERR, err.String())
|
||||
m.Push(CMD_OUT, out.String())
|
||||
m.Echo(out.String())
|
||||
}
|
||||
|
||||
const SYSTEM = "system"
|
||||
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
SYSTEM: {Name: "system", Help: "系统命令", Value: kit.Data()},
|
||||
SYSTEM: {Name: SYSTEM, Help: "系统命令", Value: kit.Data()},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
SYSTEM: {Name: "system cmd 执行:button 清空:button", Help: "系统命令", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
|
||||
SYSTEM: {Name: "system id auto", Help: "系统命令", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
|
||||
if len(arg) == 0 || kit.Int(arg[0]) > 0 {
|
||||
m.Option("_control", "_page")
|
||||
m.Option(mdb.FIELDS, kit.Select("time,id,cmd,dir,env", mdb.DETAIL, len(arg) > 0))
|
||||
m.Cmdy(mdb.SELECT, SYSTEM, "", mdb.LIST, kit.MDB_ID, arg)
|
||||
return
|
||||
}
|
||||
|
||||
if len(arg) == 1 {
|
||||
arg = kit.Split(arg[0])
|
||||
}
|
||||
cmd := exec.Command(arg[0], arg[1:]...)
|
||||
|
||||
// 运行目录
|
||||
@ -83,29 +111,6 @@ func init() {
|
||||
_system_show(m, cmd)
|
||||
}
|
||||
}},
|
||||
"ssh_user": {Name: "ssh_user", Help: "ssh_user", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
|
||||
msg := m.Cmd(SYSTEM, "who")
|
||||
msg.Split(msg.Result(), "name term begin", " \t", "\n")
|
||||
msg.Table(func(index int, value map[string]string, head []string) {
|
||||
m.Push("name", value["name"])
|
||||
m.Push("term", value["term"])
|
||||
|
||||
ls := strings.Split(value["begin"], "(")
|
||||
ls[0] = strings.Join(kit.Split(ls[0], " \t"), " ")
|
||||
if len(ls) > 1 {
|
||||
m.Push("ip", strings.TrimSuffix(ls[1], ")"))
|
||||
}
|
||||
|
||||
t, e := time.ParseInLocation("2006 Jan 2 15:04", "2020 "+ls[0], time.Local)
|
||||
if e != nil {
|
||||
t, _ = time.ParseInLocation("2006-01-02 15:04", ls[0], time.Local)
|
||||
}
|
||||
m.Push("begin", t.Format("2006-01-02 15:04:05"))
|
||||
d := time.Since(t)
|
||||
d = d / time.Millisecond * time.Millisecond
|
||||
m.Push("duration", d.String())
|
||||
})
|
||||
}},
|
||||
},
|
||||
}, nil)
|
||||
}
|
||||
|
@ -8,19 +8,15 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func _command_list(m *ice.Message, all bool, name string) {
|
||||
func _command_list(m *ice.Message, name string) {
|
||||
p := m.Spawn(m.Source())
|
||||
if all {
|
||||
p = ice.Pulse
|
||||
}
|
||||
|
||||
if name != "" {
|
||||
p.Search(name, func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) {
|
||||
m.Push("key", s.Cap(ice.CTX_FOLLOW))
|
||||
m.Push("name", kit.Format(cmd.Name))
|
||||
m.Push("help", kit.Simple(cmd.Help)[0])
|
||||
m.Push("meta", kit.Format(cmd.Meta))
|
||||
m.Push("list", kit.Format(cmd.List))
|
||||
m.Push("meta", kit.Formats(cmd.Meta))
|
||||
m.Push("list", kit.Formats(cmd.List))
|
||||
})
|
||||
return
|
||||
}
|
||||
@ -28,8 +24,7 @@ func _command_list(m *ice.Message, all bool, name string) {
|
||||
list := []string{}
|
||||
for k := range p.Target().Commands {
|
||||
if k[0] == '/' || k[0] == '_' {
|
||||
// 内部命令
|
||||
continue
|
||||
continue // 内部命令
|
||||
}
|
||||
list = append(list, k)
|
||||
}
|
||||
@ -48,9 +43,8 @@ const COMMAND = "command"
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Commands: map[string]*ice.Command{
|
||||
COMMAND: {Name: "command [all] command", Help: "命令", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
all, arg := _parse_arg_all(m, arg...)
|
||||
_command_list(m, all, strings.Join(arg, "."))
|
||||
COMMAND: {Name: "command key auto", Help: "命令", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
_command_list(m, strings.Join(arg, "."))
|
||||
}},
|
||||
},
|
||||
}, nil)
|
@ -12,17 +12,13 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func _config_list(m *ice.Message, all bool) {
|
||||
func _config_list(m *ice.Message) {
|
||||
p := m.Spawn(m.Source())
|
||||
if all {
|
||||
p = ice.Pulse
|
||||
}
|
||||
|
||||
list := []string{}
|
||||
for k := range p.Target().Configs {
|
||||
if k[0] == '/' || k[0] == '_' {
|
||||
// 内部命令
|
||||
continue
|
||||
continue // 内部配置
|
||||
}
|
||||
list = append(list, k)
|
||||
}
|
||||
@ -85,19 +81,19 @@ func _config_make(m *ice.Message, chain string, arg ...string) {
|
||||
}
|
||||
}
|
||||
func _config_rich(m *ice.Message, name string, key string, arg ...string) {
|
||||
m.Rich(name, key, kit.Dict(arg))
|
||||
m.Rich(name, key, kit.Data(arg))
|
||||
}
|
||||
func _config_grow(m *ice.Message, name string, key string, arg ...string) {
|
||||
m.Grow(name, key, kit.Dict(arg))
|
||||
}
|
||||
|
||||
const CONFIG = "config"
|
||||
const (
|
||||
SAVE = "save"
|
||||
LOAD = "load"
|
||||
RICH = "rich"
|
||||
GROW = "grow"
|
||||
)
|
||||
const CONFIG = "config"
|
||||
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
@ -105,7 +101,7 @@ func init() {
|
||||
CONFIG: {Name: "config", Help: "配置", Value: kit.Data("path", "var/conf")},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
CONFIG: {Name: "config [all] [chain [key [arg...]]]", Help: "配置", Action: map[string]*ice.Action{
|
||||
CONFIG: {Name: "config key auto", Help: "配置", Action: map[string]*ice.Action{
|
||||
SAVE: {Name: "save", Help: "保存", Hand: func(m *ice.Message, arg ...string) {
|
||||
_config_save(m, arg[0], arg[1:]...)
|
||||
}},
|
||||
@ -119,8 +115,8 @@ func init() {
|
||||
_config_grow(m, arg[0], arg[1], arg[2:]...)
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if all, arg := _parse_arg_all(m, arg...); len(arg) == 0 {
|
||||
_config_list(m, all)
|
||||
if len(arg) == 0 {
|
||||
_config_list(m)
|
||||
return
|
||||
}
|
||||
_config_make(m, arg[0], arg[1:]...)
|
39
base/ctx/context.go
Normal file
39
base/ctx/context.go
Normal file
@ -0,0 +1,39 @@
|
||||
package ctx
|
||||
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
)
|
||||
|
||||
func _context_list(m *ice.Message, all bool) {
|
||||
m.Travel(func(p *ice.Context, s *ice.Context) {
|
||||
m.Push(kit.MDB_NAME, kit.Select("ice", s.Cap(ice.CTX_FOLLOW)))
|
||||
m.Push(ice.CTX_STATUS, s.Cap(ice.CTX_STATUS))
|
||||
m.Push(ice.CTX_STREAM, s.Cap(ice.CTX_STREAM))
|
||||
m.Push(kit.MDB_HELP, s.Help)
|
||||
})
|
||||
}
|
||||
|
||||
const CONTEXT = "context"
|
||||
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Commands: map[string]*ice.Command{
|
||||
CONTEXT: {Name: "context name=web.chat action=context,command,config key auto", Help: "模块", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Search(kit.Select("ice", arg, 0)+".", func(p *ice.Context, s *ice.Context, key string) {
|
||||
msg := m.Spawn(s)
|
||||
defer m.Copy(msg)
|
||||
|
||||
switch kit.Select(CONTEXT, arg, 1) {
|
||||
case CONTEXT:
|
||||
_context_list(msg, true)
|
||||
case COMMAND:
|
||||
msg.Cmdy(COMMAND, arg[2:])
|
||||
case CONFIG:
|
||||
msg.Cmdy(CONFIG, arg[2:])
|
||||
}
|
||||
})
|
||||
}},
|
||||
},
|
||||
}, nil)
|
||||
}
|
@ -1,68 +1,15 @@
|
||||
package ctx
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"strings"
|
||||
)
|
||||
|
||||
func _parse_arg_all(m *ice.Message, arg ...string) (bool, []string) {
|
||||
if len(arg) > 0 && arg[0] == "all" {
|
||||
return true, arg[1:]
|
||||
}
|
||||
return false, arg
|
||||
}
|
||||
|
||||
func _context_list(m *ice.Message, all bool) {
|
||||
p := m.Spawn(m.Source())
|
||||
if all {
|
||||
p = ice.Pulse
|
||||
}
|
||||
|
||||
p.Travel(func(p *ice.Context, s *ice.Context) {
|
||||
if p != nil {
|
||||
m.Push("ups", kit.Select("shy", p.Cap(ice.CTX_FOLLOW)))
|
||||
} else {
|
||||
m.Push("ups", "shy")
|
||||
}
|
||||
m.Push(kit.MDB_NAME, s.Name)
|
||||
m.Push(ice.CTX_STATUS, s.Cap(ice.CTX_STATUS))
|
||||
m.Push(ice.CTX_STREAM, s.Cap(ice.CTX_STREAM))
|
||||
m.Push("help", s.Help)
|
||||
})
|
||||
}
|
||||
|
||||
const CONTEXT = "context"
|
||||
|
||||
var Index = &ice.Context{Name: "ctx", Help: "配置模块",
|
||||
Commands: map[string]*ice.Command{
|
||||
CONTEXT: {Name: "context [all] [name [command|config arg...]]", Help: "模块", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if all, arg := _parse_arg_all(m, arg...); len(arg) == 0 {
|
||||
_context_list(m, all)
|
||||
return
|
||||
}
|
||||
|
||||
if len(arg) > 1 && arg[1] == COMMAND {
|
||||
m.Search(arg[0]+".", func(sup *ice.Context, sub *ice.Context, key string) {
|
||||
m.Copy(m.Spawn(sub).Cmd(COMMAND, arg[2:]))
|
||||
})
|
||||
} else {
|
||||
m.Search(arg[0]+".", func(p *ice.Context, s *ice.Context, key string) {
|
||||
msg := m.Spawn(s)
|
||||
switch kit.Select(CONTEXT, arg, 1) {
|
||||
case CONTEXT:
|
||||
_context_list(msg, true)
|
||||
case COMMAND:
|
||||
msg.Cmdy(COMMAND, arg[0], arg[2:])
|
||||
case CONFIG:
|
||||
msg.Cmdy(CONFIG, arg[2:])
|
||||
}
|
||||
m.Copy(msg)
|
||||
})
|
||||
}
|
||||
}},
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmd(mdb.SEARCH, mdb.CREATE, COMMAND, m.AddCmd(&ice.Command{Hand: func(m *ice.Message, c *ice.Context, cc string, arg ...string) {
|
||||
arg = arg[1:]
|
||||
|
6
base/ctx/ctx.shy
Normal file
6
base/ctx/ctx.shy
Normal file
@ -0,0 +1,6 @@
|
||||
chapter "ctx"
|
||||
|
||||
field "模块" context
|
||||
field "命令" command
|
||||
field "配置" config
|
||||
|
@ -13,7 +13,7 @@ func _event_listen(m *ice.Message, event string, cmd string) {
|
||||
func _event_action(m *ice.Message, event string, arg ...string) {
|
||||
m.Option(mdb.FIELDS, "time,id,cmd")
|
||||
m.Cmd(mdb.SELECT, EVENT, kit.Keys(kit.MDB_HASH, kit.Hashs(event)), mdb.LIST).Table(func(index int, value map[string]string, head []string) {
|
||||
m.Cmd(kit.Split(value[kit.SSH_CMD]), event, arg).Cost("event %v %v", event, arg)
|
||||
m.Cmd(kit.Split(value[kit.SSH_CMD]), event, arg).Cost(EVENT, event, "arg", arg)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
const LEX = "lex"
|
||||
|
||||
var Index = &ice.Context{Name: LEX, Help: "词法模块",
|
||||
Configs: map[string]*ice.Config{},
|
||||
Commands: map[string]*ice.Command{
|
||||
"hi": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Echo("hello %s world", c.Name)
|
||||
|
@ -12,13 +12,13 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func _fields(m *ice.Message) []string {
|
||||
return kit.Split(kit.Select("time,hash,type,name,text", strings.Join(kit.Simple(m.Optionv(FIELDS)), ",")))
|
||||
}
|
||||
func _file_name(m *ice.Message, arg ...string) string {
|
||||
return kit.Select(path.Join("usr/export", path.Join(arg[:2]...)), arg, 3)
|
||||
}
|
||||
|
||||
func _hash_fields(m *ice.Message) []string {
|
||||
return kit.Split(kit.Select("time,hash,type,name,text", strings.Join(kit.Simple(m.Optionv(FIELDS)), ",")))
|
||||
}
|
||||
func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) {
|
||||
m.Log_INSERT(kit.MDB_KEY, path.Join(prefix, chain), arg[0], arg[1])
|
||||
m.Echo(m.Rich(prefix, chain, kit.Data(arg)))
|
||||
@ -33,7 +33,7 @@ func _hash_select(m *ice.Message, prefix, chain, field, value string) {
|
||||
if field == kit.MDB_HASH && value == RANDOM {
|
||||
value = kit.MDB_RANDOMS
|
||||
}
|
||||
fields := _fields(m)
|
||||
fields := _hash_fields(m)
|
||||
m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) {
|
||||
if val[kit.MDB_META] != nil {
|
||||
val = val[kit.MDB_META].(map[string]interface{})
|
||||
@ -86,13 +86,11 @@ func _hash_import(m *ice.Message, prefix, chain, file string) {
|
||||
count := 0
|
||||
if m.Conf(prefix, kit.Keys(chain, kit.MDB_META, kit.MDB_SHORT)) == "" {
|
||||
for k, data := range list {
|
||||
// 导入数据
|
||||
m.Conf(prefix, kit.Keys(chain, kit.MDB_HASH, k), data)
|
||||
count++
|
||||
}
|
||||
} else {
|
||||
for _, data := range list {
|
||||
// 导入数据
|
||||
m.Rich(prefix, chain, data)
|
||||
count++
|
||||
}
|
||||
@ -102,7 +100,7 @@ func _hash_import(m *ice.Message, prefix, chain, file string) {
|
||||
m.Echo("%d", count)
|
||||
}
|
||||
func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) {
|
||||
fields := kit.Split(kit.Select("time,hash,type,name,text", m.Option(FIELDS)))
|
||||
fields := _hash_fields(m)
|
||||
m.Richs(prefix, chain, kit.MDB_FOREACH, func(key string, val map[string]interface{}) {
|
||||
if val[kit.MDB_META] != nil {
|
||||
val = val[kit.MDB_META].(map[string]interface{})
|
||||
@ -137,6 +135,9 @@ func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) {
|
||||
m.Sort(kit.MDB_COUNT, "int_r")
|
||||
}
|
||||
|
||||
func _list_fields(m *ice.Message) []string {
|
||||
return kit.Split(kit.Select("time,id,type,name,text", strings.Join(kit.Simple(m.Optionv(FIELDS)), ",")))
|
||||
}
|
||||
func _list_insert(m *ice.Message, prefix, chain string, arg ...string) {
|
||||
m.Log_INSERT(kit.MDB_KEY, path.Join(prefix, chain), arg[0], arg[1])
|
||||
m.Echo("%d", m.Grow(prefix, chain, kit.Dict(arg)))
|
||||
@ -144,8 +145,11 @@ func _list_insert(m *ice.Message, prefix, chain string, arg ...string) {
|
||||
func _list_delete(m *ice.Message, prefix, chain, field, value string) {
|
||||
}
|
||||
func _list_select(m *ice.Message, prefix, chain, field, value string) {
|
||||
fields := kit.Split(kit.Select("time,id,type,name,text", m.Option(FIELDS)))
|
||||
m.Grows(prefix, chain, field, value, func(index int, val map[string]interface{}) {
|
||||
if value == "" {
|
||||
field = ""
|
||||
}
|
||||
fields := _list_fields(m)
|
||||
m.Grows(prefix, chain, kit.Select(m.Option("cache.field"), field), kit.Select(m.Option("cache.value"), value), func(index int, val map[string]interface{}) {
|
||||
if val[kit.MDB_META] != nil {
|
||||
val = val[kit.MDB_META].(map[string]interface{})
|
||||
}
|
||||
@ -257,9 +261,12 @@ func _list_inputs(m *ice.Message, prefix, chain string, field, value string) {
|
||||
m.Sort(kit.MDB_COUNT, "int_r")
|
||||
}
|
||||
|
||||
func _zone_fields(m *ice.Message) []string {
|
||||
return kit.Split(kit.Select("zone,id,time,type,name,text", strings.Join(kit.Simple(m.Optionv(FIELDS)), ",")))
|
||||
}
|
||||
func _zone_select(m *ice.Message, prefix, chain, zone string, id string) {
|
||||
cb := m.Optionv("cache.cb")
|
||||
fields := kit.Split(kit.Select("zone,id,time,type,name,text", m.Option(FIELDS)))
|
||||
fields := _zone_fields(m)
|
||||
m.Richs(prefix, chain, kit.Select(kit.MDB_FOREACH, zone), func(key string, val map[string]interface{}) {
|
||||
if val[kit.MDB_META] != nil {
|
||||
val = val[kit.MDB_META].(map[string]interface{})
|
||||
@ -301,7 +308,7 @@ func _zone_export(m *ice.Message, prefix, chain, file string) {
|
||||
w := csv.NewWriter(f)
|
||||
defer w.Flush()
|
||||
|
||||
fields := kit.Split(kit.Select("zone,id,time,type,name,text", m.Option(FIELDS)))
|
||||
fields := _zone_fields(m)
|
||||
w.Write(fields)
|
||||
|
||||
count := 0
|
||||
|
@ -1,71 +0,0 @@
|
||||
package ssh
|
||||
|
||||
func (f *Frame) history(m *ice.Message, line string) string {
|
||||
favor := m.Conf(SOURCE, kit.Keys(kit.MDB_META, web.FAVOR))
|
||||
if strings.HasPrefix(strings.TrimSpace(line), "!!") {
|
||||
if len(line) == 2 {
|
||||
line = m.Cmd(web.FAVOR, favor).Append(kit.MDB_TEXT)
|
||||
}
|
||||
} else if strings.HasPrefix(strings.TrimSpace(line), "!") {
|
||||
if len(line) == 1 {
|
||||
// 历史记录
|
||||
msg := m.Cmd(web.FAVOR, favor)
|
||||
msg.Sort(kit.MDB_ID)
|
||||
msg.Appendv(ice.MSG_APPEND, kit.MDB_TIME, kit.MDB_ID, kit.MDB_TEXT)
|
||||
f.printf(m, msg.Table().Result())
|
||||
return ""
|
||||
}
|
||||
if i, e := strconv.Atoi(line[1:]); e == nil {
|
||||
// 历史命令
|
||||
line = kit.Format(kit.Value(m.Cmd(web.FAVOR, favor, i).Optionv("value"), kit.MDB_TEXT))
|
||||
} else {
|
||||
f.printf(m, m.Cmd("history", "search", line[1:]).Table().Result())
|
||||
return ""
|
||||
}
|
||||
} else if strings.TrimSpace(line) != "" && f.source == STDIO {
|
||||
// 记录历史
|
||||
m.Cmd(web.FAVOR, favor, "cmd", f.source, line)
|
||||
}
|
||||
return line
|
||||
}
|
||||
|
||||
const (
|
||||
REMOTE = "remote"
|
||||
QRCODE = "qrcode"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
REMOTE: {Name: "remote", Help: "远程连接", Value: kit.Data()},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
|
||||
QRCODE: {Name: "qrcode arg...", Help: "命令提示", Action: map[string]*ice.Action{
|
||||
"json": {Name: "json [key val]...", Help: "json", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(cli.PYTHON, QRCODE, kit.Format(kit.Parse(nil, "", arg...)))
|
||||
m.Render(ice.RENDER_RESULT)
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmdy(cli.PYTHON, QRCODE, strings.Join(arg, ""))
|
||||
m.Render(ice.RENDER_RESULT)
|
||||
}},
|
||||
REMOTE: {Name: "remote user remote port local", Help: "远程连接", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
key := m.Rich(REMOTE, nil, kit.Dict(
|
||||
"user", arg[0], "remote", arg[1], "port", arg[2], "local", arg[3],
|
||||
))
|
||||
m.Echo(key)
|
||||
m.Info(key)
|
||||
|
||||
m.Gos(m, func(m *ice.Message) {
|
||||
for {
|
||||
m.Cmd(cli.SYSTEM, "ssh", "-CNR", kit.Format("%s:%s:22", arg[2], kit.Select("localhost", arg, 3)),
|
||||
kit.Format("%s@%s", arg[0], arg[1]))
|
||||
m.Info("reconnect after 10s")
|
||||
time.Sleep(time.Second * 10)
|
||||
}
|
||||
})
|
||||
}},
|
||||
},
|
||||
}, nil)
|
||||
}
|
@ -52,7 +52,7 @@ func _ssh_watch(m *ice.Message, meta map[string]string, h string, input io.Reade
|
||||
switch buf[i] {
|
||||
case '\r', '\n':
|
||||
cmd := strings.TrimSpace(string(buf[:i]))
|
||||
m.Log_IMPORT(aaa.HOSTNAME, meta[aaa.HOSTNAME], aaa.USERNAME, meta[aaa.USERNAME], CMD, cmd)
|
||||
m.Log_IMPORT(tcp.HOSTNAME, meta[tcp.HOSTNAME], aaa.USERNAME, meta[aaa.USERNAME], CMD, cmd)
|
||||
m.Cmdy(mdb.INSERT, CHANNEL, kit.Keys(kit.MDB_HASH, h), mdb.LIST, kit.MDB_TYPE, CMD, kit.MDB_TEXT, cmd)
|
||||
i = 0
|
||||
default:
|
||||
|
@ -24,7 +24,7 @@ func _ssh_conn(m *ice.Message, conn net.Conn, username, hostport string) (*ssh.C
|
||||
|
||||
c, chans, reqs, err := ssh.NewClientConn(conn, hostport, &ssh.ClientConfig{
|
||||
User: username, Auth: methods, HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
||||
m.Logs(CONNECT, aaa.HOSTNAME, hostname, aaa.HOSTPORT, remote.String())
|
||||
m.Logs(CONNECT, tcp.HOSTNAME, hostname, tcp.HOSTPORT, remote.String())
|
||||
return nil
|
||||
},
|
||||
})
|
||||
|
@ -283,7 +283,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
|
||||
r, f.stdout = os.Stdin, os.Stdout
|
||||
|
||||
m.Option("_option", ice.MSG_USERNAME)
|
||||
m.Option(ice.MSG_USERNAME, cli.UserName)
|
||||
m.Option(ice.MSG_USERNAME, ice.Info.UserName)
|
||||
m.Option(ice.MSG_USERROLE, aaa.ROOT)
|
||||
m.Option(ice.MSG_USERZONE, "boot")
|
||||
aaa.UserRoot(m)
|
||||
@ -355,7 +355,7 @@ func init() {
|
||||
}
|
||||
|
||||
if arg[0] == STDIO {
|
||||
m.Option("_control", "page")
|
||||
m.Option("_control", "_page")
|
||||
} else {
|
||||
m.Option("cache.limit", "-1")
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
)
|
||||
|
||||
func _ssh_meta(conn ssh.ConnMetadata) map[string]string {
|
||||
return map[string]string{aaa.USERNAME: conn.User(), aaa.HOSTPORT: conn.RemoteAddr().String()}
|
||||
return map[string]string{aaa.USERNAME: conn.User(), tcp.HOSTPORT: conn.RemoteAddr().String()}
|
||||
}
|
||||
|
||||
func _ssh_config(m *ice.Message, h string) *ssh.ServerConfig {
|
||||
@ -31,7 +31,7 @@ func _ssh_config(m *ice.Message, h string) *ssh.ServerConfig {
|
||||
PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
|
||||
meta, err := _ssh_meta(conn), errors.New(ice.ErrNotAuth)
|
||||
if tcp.IsLocalHost(m, strings.Split(conn.RemoteAddr().String(), ":")[0]) {
|
||||
m.Log_AUTH(aaa.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User())
|
||||
m.Log_AUTH(tcp.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User())
|
||||
err = nil // 本机用户
|
||||
} else {
|
||||
m.Cmd(mdb.SELECT, SERVICE, kit.Keys(kit.MDB_HASH, h), mdb.LIST).Table(func(index int, value map[string]string, head []string) {
|
||||
@ -42,8 +42,8 @@ func _ssh_config(m *ice.Message, h string) *ssh.ServerConfig {
|
||||
if pub, e := ssh.ParsePublicKey([]byte(s)); !m.Warn(e != nil, e) {
|
||||
|
||||
if bytes.Compare(pub.Marshal(), key.Marshal()) == 0 {
|
||||
m.Log_AUTH(aaa.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User(), aaa.HOSTNAME, value[kit.MDB_NAME])
|
||||
meta[aaa.HOSTNAME] = kit.Select("", kit.Split(value[kit.MDB_NAME], "@"), 1)
|
||||
m.Log_AUTH(tcp.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User(), tcp.HOSTNAME, value[kit.MDB_NAME])
|
||||
meta[tcp.HOSTNAME] = kit.Select("", kit.Split(value[kit.MDB_NAME], "@"), 1)
|
||||
err = nil // 认证成功
|
||||
}
|
||||
}
|
||||
@ -56,7 +56,7 @@ func _ssh_config(m *ice.Message, h string) *ssh.ServerConfig {
|
||||
meta, err := _ssh_meta(conn), errors.New(ice.ErrNotAuth)
|
||||
m.Richs(aaa.USER, "", conn.User(), func(k string, value map[string]interface{}) {
|
||||
if string(password) == kit.Format(value[aaa.PASSWORD]) {
|
||||
m.Log_AUTH(aaa.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User(), aaa.PASSWORD, strings.Repeat("*", len(kit.Format(value[aaa.PASSWORD]))))
|
||||
m.Log_AUTH(tcp.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User(), aaa.PASSWORD, strings.Repeat("*", len(kit.Format(value[aaa.PASSWORD]))))
|
||||
err = nil // 密码登录
|
||||
}
|
||||
})
|
||||
@ -64,7 +64,7 @@ func _ssh_config(m *ice.Message, h string) *ssh.ServerConfig {
|
||||
},
|
||||
|
||||
BannerCallback: func(conn ssh.ConnMetadata) string {
|
||||
m.Log_IMPORT(aaa.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User())
|
||||
m.Log_IMPORT(tcp.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User())
|
||||
return m.Conf(SERVICE, "meta.welcome")
|
||||
},
|
||||
}
|
||||
@ -94,8 +94,8 @@ func _ssh_accept(m *ice.Message, h string, c net.Conn) {
|
||||
}
|
||||
}
|
||||
func _ssh_handle(m *ice.Message, meta map[string]string, c net.Conn, channel ssh.Channel, requests <-chan *ssh.Request) {
|
||||
m.Logs(CHANNEL, aaa.HOSTPORT, c.RemoteAddr(), "->", c.LocalAddr())
|
||||
defer m.Logs("dischan", aaa.HOSTPORT, c.RemoteAddr(), "->", c.LocalAddr())
|
||||
m.Logs(CHANNEL, tcp.HOSTPORT, c.RemoteAddr(), "->", c.LocalAddr())
|
||||
defer m.Logs("dischan", tcp.HOSTPORT, c.RemoteAddr(), "->", c.LocalAddr())
|
||||
|
||||
shell := kit.Select("bash", os.Getenv("SHELL"))
|
||||
list := []string{"PATH=" + os.Getenv("PATH")}
|
||||
@ -110,7 +110,7 @@ func _ssh_handle(m *ice.Message, meta map[string]string, c net.Conn, channel ssh
|
||||
meta[CHANNEL] = h
|
||||
|
||||
for request := range requests {
|
||||
m.Logs("request", aaa.HOSTPORT, c.RemoteAddr(), kit.MDB_TYPE, request.Type)
|
||||
m.Logs("request", tcp.HOSTPORT, c.RemoteAddr(), kit.MDB_TYPE, request.Type)
|
||||
|
||||
switch request.Type {
|
||||
case "pty-req":
|
||||
|
@ -14,7 +14,7 @@ var Index = &ice.Context{Name: SSH, Help: "终端模块", Commands: map[string]*
|
||||
}},
|
||||
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if _, ok := m.Target().Server().(*Frame); ok {
|
||||
m.Done()
|
||||
m.Done(true)
|
||||
}
|
||||
m.Richs(SERVICE, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
|
||||
kit.Value(value, "meta.status", tcp.CLOSE)
|
||||
|
@ -56,10 +56,11 @@ func init() {
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
CLIENT: {Name: "client hash auto 清理", Help: "客户端", Action: map[string]*ice.Action{
|
||||
DIAL: {Name: "dial port=9010 host=", Help: "连接", Hand: func(m *ice.Message, arg ...string) {
|
||||
DIAL: {Name: "dial type name port=9010 host=", Help: "连接", Hand: func(m *ice.Message, arg ...string) {
|
||||
c, e := net.Dial(TCP, m.Option(HOST)+":"+m.Option(PORT))
|
||||
h := m.Cmdx(mdb.INSERT, CLIENT, "", mdb.HASH, PORT, m.Option(PORT), HOST, m.Option(HOST),
|
||||
kit.MDB_NAME, m.Option(kit.MDB_NAME), kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e))
|
||||
kit.MDB_TYPE, m.Option(kit.MDB_TYPE), kit.MDB_NAME, m.Option(kit.MDB_NAME),
|
||||
kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e))
|
||||
|
||||
c = &Conn{m: m, h: h, s: &Stat{}, Conn: c}
|
||||
if e == nil {
|
||||
@ -92,10 +93,10 @@ func init() {
|
||||
m.Cmdy(mdb.PRUNES, CLIENT, "", mdb.HASH, kit.MDB_STATUS, CLOSE)
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Option(mdb.FIELDS, kit.Select("time,hash,status,name,host,port,error,nread,nwrite", mdb.DETAIL, len(arg) > 0))
|
||||
m.Option(mdb.FIELDS, kit.Select("time,hash,status,type,name,host,port,error,nread,nwrite", mdb.DETAIL, len(arg) > 0))
|
||||
if m.Cmdy(mdb.SELECT, CLIENT, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 {
|
||||
m.Table(func(index int, value map[string]string, head []string) {
|
||||
m.PushButton(kit.Select("", "删除", value[kit.MDB_STATUS] == CLOSE))
|
||||
m.PushButton(kit.Select("", "删除", value[kit.MDB_STATUS] == OPEN))
|
||||
})
|
||||
}
|
||||
}},
|
||||
|
@ -60,6 +60,10 @@ func _islocalhost(m *ice.Message, ip string) (ok bool) {
|
||||
}
|
||||
func IsLocalHost(m *ice.Message, ip string) bool { return _islocalhost(m, ip) }
|
||||
|
||||
const (
|
||||
HOSTPORT = "hostport"
|
||||
HOSTNAME = "hostname"
|
||||
)
|
||||
const HOST = "host"
|
||||
|
||||
func init() {
|
||||
|
@ -27,7 +27,8 @@ func (l Listener) Accept() (net.Conn, error) {
|
||||
ls = strings.Split(strings.TrimPrefix(c.RemoteAddr().String(), "["), "]:")
|
||||
}
|
||||
h := l.m.Cmdx(mdb.INSERT, CLIENT, "", mdb.HASH, HOST, ls[0], PORT, ls[1],
|
||||
kit.MDB_NAME, l.m.Option(kit.MDB_NAME), kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e))
|
||||
kit.MDB_TYPE, l.m.Option(kit.MDB_TYPE), kit.MDB_NAME, l.m.Option(kit.MDB_NAME),
|
||||
kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e))
|
||||
|
||||
return &Conn{m: l.m, h: h, s: &Stat{}, Conn: c}, e
|
||||
}
|
||||
@ -50,10 +51,10 @@ func init() {
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
SERVER: {Name: "server hash auto 清理", Help: "服务器", Action: map[string]*ice.Action{
|
||||
LISTEN: {Name: "LISTEN port=9010 host=", Help: "监听", Hand: func(m *ice.Message, arg ...string) {
|
||||
LISTEN: {Name: "LISTEN type name port=9010 host=", Help: "监听", Hand: func(m *ice.Message, arg ...string) {
|
||||
l, e := net.Listen(TCP, m.Option(HOST)+":"+m.Option(PORT))
|
||||
h := m.Cmdx(mdb.INSERT, SERVER, "", mdb.HASH, PORT, m.Option(PORT), HOST, m.Option(HOST),
|
||||
kit.MDB_NAME, m.Option(kit.MDB_NAME), kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e))
|
||||
h := m.Cmdx(mdb.INSERT, SERVER, "", mdb.HASH, arg,
|
||||
kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e))
|
||||
|
||||
l = &Listener{m: m, h: h, s: &Stat{}, Listener: l}
|
||||
if e == nil {
|
||||
@ -105,7 +106,7 @@ func init() {
|
||||
m.Cmdy(mdb.PRUNES, SERVER, "", mdb.HASH, kit.MDB_STATUS, CLOSE)
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Option(mdb.FIELDS, kit.Select("time,hash,status,name,host,port,error,nconn", mdb.DETAIL, len(arg) > 0))
|
||||
m.Option(mdb.FIELDS, kit.Select("time,hash,status,type,name,host,port,error,nconn", mdb.DETAIL, len(arg) > 0))
|
||||
if m.Cmdy(mdb.SELECT, SERVER, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 {
|
||||
m.Table(func(index int, value map[string]string, head []string) {
|
||||
m.PushButton(kit.Select("", "删除", value[kit.MDB_STATUS] == CLOSE))
|
||||
|
@ -13,31 +13,13 @@ import (
|
||||
)
|
||||
|
||||
func _cache_name(m *ice.Message, h string) string {
|
||||
return path.Join(m.Conf(CACHE, "meta.path"), h[:2], h)
|
||||
}
|
||||
|
||||
func _cache_list(m *ice.Message, key string) {
|
||||
if key == "" {
|
||||
m.Grows(CACHE, nil, "", "", func(index int, value map[string]interface{}) {
|
||||
// 缓存列表
|
||||
m.Push("", value, []string{kit.MDB_TIME, kit.MDB_ID, DATA, 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})
|
||||
})
|
||||
m.Sort(kit.MDB_ID, "int_r")
|
||||
return
|
||||
}
|
||||
m.Richs(CACHE, nil, key, func(key string, value map[string]interface{}) {
|
||||
// 缓存详情
|
||||
m.Push("detail", value)
|
||||
})
|
||||
return path.Join(m.Conf(CACHE, kit.META_PATH), h[:2], h)
|
||||
}
|
||||
func _cache_save(m *ice.Message, kind, name, text string, arg ...string) { // file size
|
||||
if name == "" {
|
||||
return
|
||||
}
|
||||
if len(text) > 512 {
|
||||
// 存入文件
|
||||
if len(text) > 512 { // 存入文件
|
||||
p := m.Cmdx(nfs.SAVE, _cache_name(m, kit.Hashs(text)), text)
|
||||
text, arg = p, kit.Simple(p, len(text))
|
||||
}
|
||||
@ -46,17 +28,9 @@ func _cache_save(m *ice.Message, kind, name, text string, arg ...string) { // fi
|
||||
size := kit.Int(kit.Select(kit.Format(len(text)), arg, 1))
|
||||
file := kit.Select("", arg, 0)
|
||||
text = kit.Select(file, text)
|
||||
h := m.Rich(CACHE, nil, kit.Dict(
|
||||
h := m.Cmdx(mdb.INSERT, CACHE, "", mdb.HASH,
|
||||
kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, text,
|
||||
kit.MDB_FILE, file, kit.MDB_SIZE, size,
|
||||
))
|
||||
m.Log_CREATE(CACHE, h, kit.MDB_TYPE, kind, kit.MDB_NAME, name)
|
||||
|
||||
// 添加记录
|
||||
m.Grow(CACHE, nil, kit.Dict(
|
||||
kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, text,
|
||||
kit.MDB_SIZE, size, DATA, h,
|
||||
))
|
||||
kit.MDB_FILE, file, kit.MDB_SIZE, size)
|
||||
|
||||
// 返回结果
|
||||
m.Push(kit.MDB_TIME, m.Time())
|
||||
@ -68,15 +42,15 @@ func _cache_save(m *ice.Message, kind, name, text string, arg ...string) { // fi
|
||||
m.Push(DATA, h)
|
||||
}
|
||||
func _cache_watch(m *ice.Message, key, file string) {
|
||||
m.Richs(CACHE, nil, key, func(key string, value map[string]interface{}) {
|
||||
if value[kit.MDB_FILE] == nil {
|
||||
m.Option(mdb.FIELDS, "time,hash,size,type,name,text,file")
|
||||
m.Cmd(mdb.SELECT, CACHE, "", mdb.HASH, kit.MDB_HASH, key).Table(func(index int, value map[string]string, head []string) {
|
||||
if value[kit.MDB_FILE] == "" {
|
||||
m.Cmdy(nfs.SAVE, file, value[kit.MDB_TEXT])
|
||||
} else {
|
||||
m.Cmdy(nfs.LINK, file, value[kit.MDB_FILE])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func _cache_catch(m *ice.Message, name string) (file, size string) {
|
||||
if f, e := os.Open(name); m.Assert(e) {
|
||||
defer f.Close()
|
||||
@ -99,7 +73,7 @@ func _cache_upload(m *ice.Message, r *http.Request) (kind, name, file, size stri
|
||||
buf.Seek(0, os.SEEK_SET)
|
||||
if n, e := io.Copy(f, buf); m.Assert(e) {
|
||||
m.Log_IMPORT(kit.MDB_FILE, p, kit.MDB_SIZE, kit.FmtSize(int64(n)))
|
||||
return h.Header.Get("Content-Type"), h.Filename, p, kit.Format(n)
|
||||
return h.Header.Get(ContentType), h.Filename, p, kit.Format(n)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -108,7 +82,7 @@ func _cache_upload(m *ice.Message, r *http.Request) (kind, name, file, size stri
|
||||
func _cache_download(m *ice.Message, r *http.Response) (file, size string) {
|
||||
defer r.Body.Close()
|
||||
|
||||
total := kit.Int(kit.Select("1", r.Header.Get("Content-Length")))
|
||||
total := kit.Int(kit.Select("1", r.Header.Get(ContentLength)))
|
||||
if f, p, e := kit.Create(path.Join("var/tmp", kit.Hashs("uniq"))); m.Assert(e) {
|
||||
size, buf := 0, make([]byte, 1024)
|
||||
for {
|
||||
@ -160,18 +134,15 @@ const CACHE = "cache"
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
CACHE: {Name: "cache", Help: "缓存池", Value: kit.Data(
|
||||
kit.MDB_SHORT, kit.MDB_TEXT,
|
||||
kit.MDB_PATH, "var/file",
|
||||
kit.MDB_STORE, "var/data",
|
||||
kit.MDB_FSIZE, "200000",
|
||||
kit.MDB_LIMIT, "50",
|
||||
kit.MDB_LEAST, "30",
|
||||
CACHE: {Name: CACHE, Help: "缓存池", Value: kit.Data(
|
||||
kit.MDB_SHORT, kit.MDB_TEXT, kit.MDB_PATH, "var/file",
|
||||
kit.MDB_STORE, "var/data", kit.MDB_FSIZE, "200000",
|
||||
kit.MDB_LIMIT, "50", kit.MDB_LEAST, "30",
|
||||
)},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
CACHE: {Name: "cache data=auto auto", Help: "缓存池", Action: map[string]*ice.Action{
|
||||
WATCH: {Name: "watch key file", Help: "查看", Hand: func(m *ice.Message, arg ...string) {
|
||||
CACHE: {Name: "cache hash auto", Help: "缓存池", Action: map[string]*ice.Action{
|
||||
WATCH: {Name: "watch key file", Help: "释放", Hand: func(m *ice.Message, arg ...string) {
|
||||
_cache_watch(m, arg[0], arg[1])
|
||||
}},
|
||||
WRITE: {Name: "write type name text", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||
@ -186,15 +157,16 @@ func init() {
|
||||
_cache_save(m, kind, name, "", file, size)
|
||||
}},
|
||||
DOWNLOAD: {Name: "download type name", Help: "下载", Hand: func(m *ice.Message, arg ...string) {
|
||||
if r, ok := m.Optionv("response").(*http.Response); ok {
|
||||
if r, ok := m.Optionv(RESPONSE).(*http.Response); ok {
|
||||
file, size := _cache_download(m, r)
|
||||
_cache_save(m, arg[0], arg[1], "", file, size)
|
||||
}
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Option(mdb.FIELDS, "time,size,type,name,text,file")
|
||||
m.Cmdy(mdb.SELECT, m.Prefix(CACHE), "", mdb.HASH, kit.MDB_HASH, arg)
|
||||
m.Option(mdb.FIELDS, "time,hash,size,type,name,text,file")
|
||||
m.Cmdy(mdb.SELECT, CACHE, "", mdb.HASH, kit.MDB_HASH, arg)
|
||||
}},
|
||||
|
||||
"/cache/": {Name: "/cache/", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Richs(CACHE, nil, arg[0], func(key string, value map[string]interface{}) {
|
||||
if value[kit.MDB_FILE] == nil {
|
||||
|
@ -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"
|
||||
|
||||
@ -14,33 +15,35 @@ import (
|
||||
)
|
||||
|
||||
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) {
|
||||
m.Cmdy(nfs.DIR, m.Conf(DREAM, kit.META_PATH), "time size 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, gdb.START)
|
||||
m.PushButton(gdb.STOP)
|
||||
}) == nil {
|
||||
m.Push(kit.MDB_TYPE, "none")
|
||||
m.Push(kit.MDB_TYPE, WORKER)
|
||||
m.Push(kit.MDB_STATUS, gdb.STOP)
|
||||
m.PushButton(gdb.START)
|
||||
}
|
||||
m.PushRender("action", "button", "start,stop,restart")
|
||||
})
|
||||
m.Sort(kit.MDB_NAME)
|
||||
m.Sort(kit.MDB_NAME, "str_r")
|
||||
}
|
||||
func _dream_show(m *ice.Message, name string) {
|
||||
// 规范命名
|
||||
if !strings.Contains(name, "-") || !strings.HasPrefix(name, "20") {
|
||||
name = m.Time("20060102-") + name
|
||||
name = m.Time("20060102-") + strings.ReplaceAll(name, "-", "_")
|
||||
}
|
||||
|
||||
// 创建目录
|
||||
p := path.Join(m.Conf(DREAM, "meta.path"), name)
|
||||
p := path.Join(m.Conf(DREAM, kit.META_PATH), name)
|
||||
os.MkdirAll(p, ice.MOD_DIR)
|
||||
|
||||
if m.Option("repos") != "" {
|
||||
m.Cmd("web.code.git.repos", "create", "remote", m.Option("repos"), "path", p)
|
||||
// 下载代码
|
||||
if m.Option(kit.SSH_REPOS) != "" {
|
||||
m.Cmd("web.code.git.repos", mdb.CREATE, kit.SSH_REPOS, m.Option(kit.SSH_REPOS), kit.MDB_PATH, p)
|
||||
}
|
||||
|
||||
// 任务脚本
|
||||
miss := path.Join(p, "etc/miss.sh")
|
||||
if _, e := os.Stat(miss); e != nil {
|
||||
m.Cmd(nfs.SAVE, miss, m.Conf(DREAM, "meta.miss"))
|
||||
@ -49,39 +52,36 @@ func _dream_show(m *ice.Message, name string) {
|
||||
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
|
||||
return // 已经启动
|
||||
}
|
||||
}
|
||||
|
||||
if m.Richs(SPACE, nil, name, nil) == nil {
|
||||
// 启动任务
|
||||
m.Option(cli.CMD_DIR, p)
|
||||
m.Option(cli.CMD_STDERR, path.Join(p, m.Conf(DREAM, "meta.env.ctx_log")))
|
||||
m.Optionv(cli.CMD_DIR, p)
|
||||
m.Optionv(cli.CMD_ENV, kit.Simple(
|
||||
"ctx_dev", m.Conf(cli.RUNTIME, "conf.ctx_dev"),
|
||||
"PATH", kit.Path(path.Join(p, "bin"))+":"+os.Getenv("PATH"),
|
||||
"USER", cli.UserName,
|
||||
m.Confv(DREAM, "meta.env"),
|
||||
"USER", ice.Info.UserName, m.Confv(DREAM, "meta.env"),
|
||||
))
|
||||
// 启动任务
|
||||
m.Optionv(cli.CMD_STDERR, path.Join(p, m.Conf(DREAM, "meta.env.ctx_log")))
|
||||
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"
|
||||
)
|
||||
const DREAM = "dream"
|
||||
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
DREAM: {Name: "dream", Help: "梦想家", Value: kit.Data("path", "usr/local/work",
|
||||
"cmd", []interface{}{"ice.bin", SPACE, "connect"}, "env", kit.Dict(
|
||||
"ctx_log", "bin/boot.log", "ctx_mod", "ctx,log,gdb,ssh",
|
||||
),
|
||||
DREAM: {Name: DREAM, Help: "梦想家", Value: kit.Data("path", "usr/local/work",
|
||||
"cmd", []interface{}{"ice.bin", SPACE, "connect"},
|
||||
"env", kit.Dict("ctx_log", "bin/boot.log"),
|
||||
"miss", `#!/bin/bash
|
||||
[ -f ~/.ish/plug.sh ] || [ -f ./.ish/plug.sh ] || git clone ${ISH_CONF_HUB_PROXY:="https://"}github.com/shylinux/intshell ./.ish
|
||||
[ "$ISH_CONF_PRE" != "" ] || source ./.ish/plug.sh || source ~/.ish/plug.sh
|
||||
@ -97,29 +97,26 @@ ish_miss_prepare_install
|
||||
)},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
DREAM: {Name: "dream [name [cmd...]] auto", Help: "梦想家", Meta: kit.Dict("detail", []interface{}{"启动", "停止"}), Action: map[string]*ice.Action{
|
||||
gdb.START: {Name: "start type name", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Option(kit.MDB_NAME, kit.Select(path.Base(m.Option(kit.SSH_REPOS)), m.Option(kit.MDB_NAME)))
|
||||
_dream_show(m, m.Option(kit.MDB_NAME))
|
||||
DREAM: {Name: "dream name path auto 启动", Help: "梦想家", Action: map[string]*ice.Action{
|
||||
gdb.START: {Name: "start type=worker,server name repos", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
|
||||
_dream_show(m, m.Option(kit.MDB_NAME, kit.Select(path.Base(m.Option(kit.SSH_REPOS)), m.Option(kit.MDB_NAME))))
|
||||
}},
|
||||
gdb.STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(SPACE, m.Option(kit.MDB_NAME), "exit", "1")
|
||||
m.Cmdy(SPACE, m.Option(kit.MDB_NAME), "exit", "0")
|
||||
}},
|
||||
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))
|
||||
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
|
||||
switch arg[0] {
|
||||
case kit.MDB_NAME:
|
||||
m.Cmdy(nfs.DIR, m.Conf(DREAM, kit.META_PATH), "name,time")
|
||||
}
|
||||
}},
|
||||
}, 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])
|
||||
m.Option(nfs.DIR_ROOT, path.Join(m.Conf(DREAM, kit.META_PATH), arg[0]))
|
||||
m.Cmdy(nfs.DIR, arg[1:])
|
||||
}},
|
||||
},
|
||||
}, nil)
|
||||
|
@ -3,7 +3,6 @@ package web
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/aaa"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
"github.com/skip2/go-qrcode"
|
||||
|
||||
@ -14,26 +13,6 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func URL(m *ice.Message, path string, arg ...interface{}) string {
|
||||
list := kit.Simple(arg)
|
||||
if m.Option("pod") != "" {
|
||||
list = append(list, "pod", m.Option("pod"))
|
||||
}
|
||||
return kit.MergeURL2(m.R.Header.Get("Origin"), path, list)
|
||||
}
|
||||
func Count(m *ice.Message, cmd, key, name string) int {
|
||||
count := kit.Int(m.Conf(cmd, kit.Keys(key, name)))
|
||||
m.Conf(cmd, kit.Keys(key, name), count+1)
|
||||
return count
|
||||
}
|
||||
func Format(key string, arg ...interface{}) string {
|
||||
switch args := kit.Simple(arg); key {
|
||||
case "a":
|
||||
return fmt.Sprintf("<a href='%s' target='_blank'>%s</a>", kit.Format(args[0]), kit.Select(kit.Format(args[0]), args, 1))
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
const (
|
||||
STATUS = "status"
|
||||
COOKIE = "cookie"
|
||||
@ -97,69 +76,7 @@ func RenderCookie(msg *ice.Message, value string, arg ...string) { // name path
|
||||
expire := time.Now().Add(kit.Duration(kit.Select(msg.Conf(aaa.SESS, "meta.expire"), arg, 2)))
|
||||
http.SetCookie(msg.W, &http.Cookie{Value: value, Name: kit.Select(ice.MSG_SESSID, arg, 0), Path: kit.Select("/", arg, 1), Expires: expire})
|
||||
}
|
||||
func RenderStatus(msg *ice.Message, code int, text string) { // name path expire
|
||||
func RenderStatus(msg *ice.Message, code int, text string) {
|
||||
msg.W.WriteHeader(code)
|
||||
msg.W.Write([]byte(text))
|
||||
}
|
||||
|
||||
var RENDER = struct {
|
||||
A string
|
||||
IMG string
|
||||
Video string
|
||||
Field string
|
||||
Frame string
|
||||
Button string
|
||||
|
||||
Download string
|
||||
}{
|
||||
A: "a",
|
||||
IMG: "img",
|
||||
Video: "video",
|
||||
Field: "field",
|
||||
Frame: "frame",
|
||||
Button: "button",
|
||||
|
||||
Download: "download",
|
||||
}
|
||||
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Commands: map[string]*ice.Command{
|
||||
"_render": {Action: map[string]*ice.Action{
|
||||
RENDER.A: {Hand: func(m *ice.Message, arg ...string) {
|
||||
// u := kit.Select(m.Conf(SHARE, "meta.domain"), arg, 1)
|
||||
u := kit.Select(arg[0], arg, 1)
|
||||
m.Echo(`<a href="%s" target="_blank">%s</a>`, u, arg[0])
|
||||
}},
|
||||
RENDER.IMG: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Echo(`<img src="%s" height=%s>`, arg[0], kit.Select("120", arg, 1))
|
||||
}},
|
||||
RENDER.Video: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Echo(`<video src="%s" height=%s controls>`, arg[0], kit.Select("120", arg, 1))
|
||||
}},
|
||||
RENDER.Field: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Echo(`<fieldset><legend>%s(%s)</legend><form></form></fieldset>`, arg[0], arg[1])
|
||||
}},
|
||||
RENDER.Frame: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Echo(`<iframe src=%s class="story" data-type="iframe" width=800 height=400 ></iframe>`, arg[0])
|
||||
}},
|
||||
RENDER.Button: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Echo(`<input type="button" value="%s">`, arg[0])
|
||||
}},
|
||||
RENDER.Download: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Echo(`<a href="%s" target="_blank" download="%s">%s</a>`, arg[0], kit.Select(path.Base(arg[0]), arg, 1), kit.Select(arg[0], arg, 1))
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if arg[0] == mdb.RENDER {
|
||||
m.Search("_render", func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) {
|
||||
if action, ok := cmd.Action[arg[1]]; ok {
|
||||
action.Hand(m, arg[2:]...)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
m.Echo(`<input type="%s" value="%s">`, arg[1], arg[2])
|
||||
}},
|
||||
},
|
||||
}, nil)
|
||||
}
|
||||
|
@ -2,9 +2,11 @@ package web
|
||||
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/aaa"
|
||||
"github.com/shylinux/icebergs/base/cli"
|
||||
"github.com/shylinux/icebergs/base/ctx"
|
||||
"github.com/shylinux/icebergs/base/gdb"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
"github.com/shylinux/icebergs/base/nfs"
|
||||
"github.com/shylinux/icebergs/base/tcp"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
)
|
||||
|
||||
@ -13,9 +15,8 @@ func _route_travel(m *ice.Message, route string) {
|
||||
m.Richs(SPACE, nil, kit.MDB_FOREACH, func(key string, val map[string]interface{}) {
|
||||
switch val[kit.MDB_TYPE] {
|
||||
case SERVER:
|
||||
if val[kit.MDB_NAME] == cli.NodeName {
|
||||
// 避免循环
|
||||
return
|
||||
if val[kit.MDB_NAME] == ice.Info.NodeName {
|
||||
return // 避免循环
|
||||
}
|
||||
|
||||
// 远程查询
|
||||
@ -46,100 +47,91 @@ func init() {
|
||||
ROUTE: {Name: ROUTE, Help: "路由器", Value: kit.Data(kit.MDB_SHORT, kit.SSH_ROUTE)},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
ROUTE: {Name: "route route ctx cmd auto 添加", Help: "路由", Action: map[string]*ice.Action{
|
||||
"inputs": {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
|
||||
switch arg[0] {
|
||||
case "cmd":
|
||||
m.Cmdy(SPACE, m.Option("route"), "command")
|
||||
case "name":
|
||||
m.Cmdy(SPACE, m.Option("route"), "dream")
|
||||
case "template":
|
||||
m.Option(nfs.DIR_DEEP, true)
|
||||
m.Cmdy(nfs.DIR, "usr/icebergs")
|
||||
m.Sort("path")
|
||||
}
|
||||
}},
|
||||
"invite": {Name: "invite", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||
ROUTE: {Name: "route route ctx cmd auto invite", Help: "路由", Action: map[string]*ice.Action{
|
||||
mdb.INVITE: {Name: "invite", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy("web.code.publish", "contexts", "tmux")
|
||||
m.Cmdy("web.code.publish", "contexts", "base")
|
||||
m.Cmdy("web.code.publish", "contexts", "miss")
|
||||
}},
|
||||
"start": {Name: "start type=worker,server name=hi@key repos", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(SPACE, m.Option("route"), "dream", "start", arg)
|
||||
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
|
||||
switch arg[0] {
|
||||
case "cmd":
|
||||
m.Cmdy(SPACE, m.Option(ROUTE), ctx.COMMAND)
|
||||
case "name":
|
||||
m.Cmdy(SPACE, m.Option(ROUTE), DREAM)
|
||||
case "template":
|
||||
m.Option(nfs.DIR_DEEP, true)
|
||||
m.Cmdy(nfs.DIR, "usr/icebergs")
|
||||
m.Sort(kit.MDB_PATH)
|
||||
}
|
||||
}},
|
||||
gdb.START: {Name: "start type=worker,server name=hi@key repos", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(SPACE, m.Option(ROUTE), DREAM, gdb.START, arg)
|
||||
m.Sleep("3s")
|
||||
}},
|
||||
gdb.STOP: {Name: "stop", Help: "结束", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(SPACE, m.Option(ROUTE), "exit")
|
||||
m.Sleep("3s")
|
||||
}},
|
||||
"gen": {Name: "gen module=hi@key template=usr/icebergs/misc/zsh/zsh.go@key", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(SPACE, m.Option("route"), "web.code.autogen",
|
||||
m.Cmdy(SPACE, m.Option(ROUTE), "web.code.autogen",
|
||||
"create", "name", m.Option("module"), "from", m.Option("template"))
|
||||
}},
|
||||
"stop": {Name: "stop", Help: "结束", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(SPACE, m.Option("route"), "exit")
|
||||
m.Sleep("3s")
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) > 3 && arg[3] == "run" {
|
||||
m.Cmdy(SPACE, arg[0], kit.Keys(arg[1], arg[2]), arg[4:])
|
||||
return
|
||||
if len(arg) == 0 || arg[0] == "" {
|
||||
if _route_travel(m, kit.Select("", arg, 0)); m.W == nil {
|
||||
return
|
||||
}
|
||||
|
||||
m.Cmd(tcp.HOST).Table(func(index int, value map[string]string, head []string) {
|
||||
m.Push(kit.MDB_TYPE, MYSELF)
|
||||
m.Push(ROUTE, value["ip"])
|
||||
})
|
||||
|
||||
m.Table(func(index int, value map[string]string, field []string) {
|
||||
switch value[kit.MDB_TYPE] {
|
||||
case MYSELF:
|
||||
m.PushRender(kit.MDB_LINK, "a", value[kit.SSH_ROUTE], m.Option(ice.MSG_USERWEB))
|
||||
default:
|
||||
m.PushRender(kit.MDB_LINK, "a", value[kit.SSH_ROUTE],
|
||||
kit.MergeURL(m.Option(ice.MSG_USERWEB), kit.SSH_POD, kit.Keys(m.Option(kit.SSH_POD, value[kit.SSH_ROUTE]))))
|
||||
}
|
||||
|
||||
switch value[kit.MDB_TYPE] {
|
||||
case MYSELF, SERVER:
|
||||
m.PushButton(gdb.START)
|
||||
case WORKER:
|
||||
m.PushButton(gdb.STOP)
|
||||
default:
|
||||
m.PushButton("")
|
||||
}
|
||||
})
|
||||
m.Sort(kit.SSH_ROUTE)
|
||||
return // 设备列表
|
||||
}
|
||||
if len(arg) > 2 && arg[0] != "" {
|
||||
m.Cmdy(SPACE, arg[0], "context", arg[1], "command", arg[2])
|
||||
|
||||
if len(arg) > 3 { // 执行命令
|
||||
m.Cmdy(SPACE, arg[0], kit.Keys(arg[1], arg[2]), arg[4:])
|
||||
|
||||
} else if len(arg) > 2 { // 加载插件
|
||||
m.Cmdy(SPACE, arg[0], ctx.CONTEXT, arg[1], ctx.COMMAND, arg[2])
|
||||
m.Option("_prefix", arg[0], arg[1], arg[2], "run")
|
||||
m.Option("_process", "_field")
|
||||
return
|
||||
}
|
||||
if len(arg) > 1 && arg[0] != "" {
|
||||
m.Cmd(SPACE, arg[0], "context", arg[1], "command").Table(func(index int, value map[string]string, head []string) {
|
||||
|
||||
} else if len(arg) > 1 { // 命令列表
|
||||
m.Cmd(SPACE, arg[0], ctx.CONTEXT, arg[1], ctx.COMMAND).Table(func(index int, value map[string]string, head []string) {
|
||||
m.Push("cmd", value["key"])
|
||||
m.Push("name", value["name"])
|
||||
m.Push("help", value["help"])
|
||||
})
|
||||
return
|
||||
}
|
||||
if len(arg) > 0 && arg[0] != "" {
|
||||
m.Cmd(SPACE, arg[0], "context").Table(func(index int, value map[string]string, head []string) {
|
||||
|
||||
} else if len(arg) > 0 { // 模块列表
|
||||
m.Cmd(SPACE, arg[0], ctx.CONTEXT).Table(func(index int, value map[string]string, head []string) {
|
||||
m.Push("ctx", kit.Keys(value["ups"], value["name"]))
|
||||
m.Push("status", value["status"])
|
||||
m.Push("stream", value["stream"])
|
||||
m.Push("help", value["help"])
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if _route_travel(m, kit.Select("", arg, 0)); m.W == nil {
|
||||
return
|
||||
}
|
||||
m.Push("type", MYSELF)
|
||||
m.Push("route", cli.NodeName)
|
||||
|
||||
m.Table(func(index int, value map[string]string, field []string) {
|
||||
m.PushRender(kit.MDB_LINK, "a", value[kit.SSH_ROUTE],
|
||||
kit.MergeURL(m.Option(ice.MSG_USERWEB), "pod", kit.Keys(m.Option("pod", value[kit.SSH_ROUTE]))))
|
||||
switch value[kit.MDB_TYPE] {
|
||||
case MYSELF, SERVER:
|
||||
m.PushRender("action", "button", "启动")
|
||||
case WORKER:
|
||||
m.PushRender("action", "button", "结束")
|
||||
}
|
||||
})
|
||||
m.Sort(kit.SSH_ROUTE)
|
||||
}},
|
||||
"/route/": {Name: "/route/", Help: "路由器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
switch arg[0] {
|
||||
case "login":
|
||||
if m.Option(ice.MSG_USERNAME) != "" {
|
||||
m.Push(ice.MSG_USERNAME, m.Option(ice.MSG_USERNAME))
|
||||
m.Info("username: %v", m.Option(ice.MSG_USERNAME))
|
||||
break
|
||||
}
|
||||
if m.Option(ice.MSG_SESSID) != "" && m.Cmdx(aaa.SESS, "check", m.Option(ice.MSG_SESSID)) != "" {
|
||||
m.Info("sessid: %v", m.Option(ice.MSG_SESSID))
|
||||
break
|
||||
}
|
||||
|
||||
sessid := m.Cmdx(aaa.SESS, "create", "")
|
||||
share := m.Cmdx(SHARE, "login", m.Option(ice.MSG_USERIP), sessid)
|
||||
Render(m, "cookie", sessid)
|
||||
m.Render(share)
|
||||
}
|
||||
}},
|
||||
}}, nil)
|
||||
|
@ -4,10 +4,10 @@ import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/aaa"
|
||||
"github.com/shylinux/icebergs/base/cli"
|
||||
"github.com/shylinux/icebergs/base/gdb"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
"github.com/shylinux/icebergs/base/tcp"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
log "github.com/shylinux/toolkits/logs"
|
||||
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
@ -16,57 +16,88 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const LOGIN = "_login"
|
||||
const (
|
||||
SERVE_START = "serve.start"
|
||||
SERVE_CLOSE = "serve.close"
|
||||
)
|
||||
|
||||
func _serve_login(msg *ice.Message, cmds []string, w http.ResponseWriter, r *http.Request) ([]string, bool) {
|
||||
msg.Option(ice.MSG_USERNAME, "")
|
||||
msg.Option(ice.MSG_USERROLE, "void")
|
||||
|
||||
if msg.Options(ice.MSG_SESSID) {
|
||||
// 会话认证
|
||||
aaa.SessCheck(msg, msg.Option(ice.MSG_SESSID))
|
||||
func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
|
||||
if r.Header.Get("index.module") != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
if !msg.Options(ice.MSG_USERNAME) && tcp.IsLocalHost(msg, msg.Option(ice.MSG_USERIP)) {
|
||||
// 自动认证
|
||||
if aaa.UserLogin(msg, cli.UserName, cli.PassWord) {
|
||||
if strings.HasPrefix(msg.Option(ice.MSG_USERUA), "Mozilla/5.0") {
|
||||
// msg.Option(ice.MSG_SESSID, aaa.SessCreate(msg, msg.Option(ice.MSG_USERNAME), msg.Option(ice.MSG_USERROLE)))
|
||||
// Render(msg, "cookie", msg.Option(ice.MSG_SESSID))
|
||||
// 解析地址
|
||||
if ip := r.Header.Get("X-Forwarded-For"); ip != "" {
|
||||
r.Header.Set(ice.MSG_USERIP, ip)
|
||||
} else if ip := r.Header.Get("X-Real-Ip"); ip != "" {
|
||||
r.Header.Set(ice.MSG_USERIP, ip)
|
||||
} else if strings.HasPrefix(r.RemoteAddr, "[") {
|
||||
r.Header.Set(ice.MSG_USERIP, strings.Split(r.RemoteAddr, "]")[0][1:])
|
||||
} else {
|
||||
r.Header.Set(ice.MSG_USERIP, strings.Split(r.RemoteAddr, ":")[0])
|
||||
}
|
||||
m.Info("").Info("%s %s %s", r.Header.Get(ice.MSG_USERIP), r.Method, r.URL)
|
||||
|
||||
// 请求地址
|
||||
r.Header.Set("index.module", m.Target().Name)
|
||||
r.Header.Set("index.path", r.URL.Path)
|
||||
r.Header.Set("index.url", r.URL.String())
|
||||
|
||||
// 输出日志
|
||||
if m.Conf(SERVE, "meta.logheaders") == "true" {
|
||||
for k, v := range r.Header {
|
||||
m.Info("%s: %v", k, kit.Format(v))
|
||||
}
|
||||
m.Info(" ")
|
||||
|
||||
defer func() {
|
||||
for k, v := range w.Header() {
|
||||
m.Info("%s: %v", k, kit.Format(v))
|
||||
}
|
||||
m.Info(" ")
|
||||
}()
|
||||
}
|
||||
|
||||
// 单点登录
|
||||
if r.URL.Path == "/" && m.Conf(SERVE, "meta.sso") != "" {
|
||||
r.ParseForm()
|
||||
sessid := r.FormValue(ice.MSG_SESSID)
|
||||
if sessid == "" {
|
||||
if c, e := r.Cookie(ice.MSG_SESSID); e == nil {
|
||||
sessid = c.Value
|
||||
}
|
||||
}
|
||||
|
||||
ok := false
|
||||
m.Richs(aaa.SESS, "", sessid, func(key string, value map[string]interface{}) {
|
||||
ok = true
|
||||
})
|
||||
|
||||
if !ok {
|
||||
http.Redirect(w, r, m.Conf(SERVE, "meta.sso"), http.StatusTemporaryRedirect)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
if _, ok := msg.Target().Commands[LOGIN]; ok {
|
||||
// 权限检查
|
||||
msg.Target().Cmd(msg, LOGIN, msg.Option(ice.MSG_USERURL), cmds...)
|
||||
cmds = kit.Simple(msg.Optionv(ice.MSG_CMDS))
|
||||
|
||||
} else if ls := strings.Split(msg.Option(ice.MSG_USERURL), "/"); msg.Conf(SERVE, kit.Keys("meta.black", ls[1])) == "true" {
|
||||
return cmds, false // black
|
||||
|
||||
} else if msg.Conf(SERVE, kit.Keys("meta.white", ls[1])) == "true" {
|
||||
return cmds, true // white
|
||||
|
||||
} else {
|
||||
if msg.Warn(!msg.Options(ice.MSG_USERNAME), "not login %s", msg.Option(ice.MSG_USERURL)) {
|
||||
msg.Render(STATUS, 401, "not login")
|
||||
return cmds, false
|
||||
}
|
||||
if msg.Warn(!msg.Right(msg.Option(ice.MSG_USERURL))) {
|
||||
msg.Render(STATUS, 403, "not auth")
|
||||
return cmds, false
|
||||
}
|
||||
if strings.HasPrefix(r.URL.Path, "/debug") {
|
||||
r.URL.Path = strings.Replace(r.URL.Path, "/debug", "/code", -1)
|
||||
return true
|
||||
}
|
||||
|
||||
return cmds, msg.Option(ice.MSG_USERURL) != ""
|
||||
if b, ok := ice.BinPack[r.URL.Path]; ok {
|
||||
if strings.HasSuffix(r.URL.Path, ".css") {
|
||||
w.Header().Set("Content-Type", "text/css; charset=utf-8")
|
||||
}
|
||||
w.Write(b)
|
||||
return false
|
||||
}
|
||||
|
||||
if r.URL.Path == "/" && strings.Contains(r.Header.Get("User-Agent"), "curl") {
|
||||
http.ServeFile(w, r, path.Join(m.Conf(SERVE, "meta.intshell.path"), m.Conf(SERVE, "meta.intshell.index")))
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.ResponseWriter, r *http.Request) {
|
||||
defer func() { msg.Cost("%s %v %v", r.URL.Path, msg.Optionv(ice.MSG_CMDS), msg.Format("append")) }()
|
||||
defer func() {
|
||||
msg.Cost(kit.Format("%s %v %v", r.URL.Path, msg.Optionv(ice.MSG_CMDS), msg.Format(ice.MSG_APPEND)))
|
||||
}()
|
||||
|
||||
// 请求变量
|
||||
msg.Option(ice.MSG_SESSID, "")
|
||||
@ -74,17 +105,16 @@ func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.Respon
|
||||
msg.Option(v.Name, v.Value)
|
||||
}
|
||||
|
||||
// 请求
|
||||
msg.Option(ice.MSG_OUTPUT, "")
|
||||
// 请求地址
|
||||
if u, e := url.Parse(r.Header.Get("Referer")); e == nil {
|
||||
for k, v := range u.Query() {
|
||||
if msg.Logs("refer", k, v); k != "name" {
|
||||
msg.Option(k, v)
|
||||
}
|
||||
msg.Logs("refer", k, v)
|
||||
msg.Option(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
// 用户请求
|
||||
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")))
|
||||
@ -98,12 +128,12 @@ func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.Respon
|
||||
}
|
||||
|
||||
// 解析引擎
|
||||
switch r.Header.Get("Content-Type") {
|
||||
case "application/json":
|
||||
switch r.Header.Get(ContentType) {
|
||||
case ContentJSON:
|
||||
var data interface{}
|
||||
if e := json.NewDecoder(r.Body).Decode(&data); !msg.Warn(e != nil, "%s", e) {
|
||||
if e := json.NewDecoder(r.Body).Decode(&data); !msg.Warn(e != nil, e) {
|
||||
msg.Optionv(ice.MSG_USERDATA, data)
|
||||
msg.Logs("json", "value", kit.Formats(data))
|
||||
msg.Logs("json", "value", kit.Format(data))
|
||||
}
|
||||
|
||||
switch d := data.(type) {
|
||||
@ -113,7 +143,7 @@ func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.Respon
|
||||
}
|
||||
}
|
||||
default:
|
||||
r.ParseMultipartForm(kit.Int64(kit.Select(r.Header.Get("Content-Length"), "4096")))
|
||||
r.ParseMultipartForm(kit.Int64(kit.Select(r.Header.Get(ContentLength), "4096")))
|
||||
if r.ParseForm(); len(r.PostForm) > 0 {
|
||||
for k, v := range r.PostForm {
|
||||
msg.Logs("form", k, v)
|
||||
@ -138,9 +168,6 @@ func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.Respon
|
||||
}
|
||||
}
|
||||
|
||||
if msg.Option("cache.begin") == "" {
|
||||
msg.Option("cache.begin", -kit.Int(msg.Option("cache.limit")))
|
||||
}
|
||||
// 执行命令
|
||||
if cmds, ok := _serve_login(msg, kit.Simple(msg.Optionv(ice.MSG_CMDS)), w, r); ok {
|
||||
msg.Option("_option", msg.Optionv(ice.MSG_OPTION))
|
||||
@ -151,111 +178,64 @@ func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.Respon
|
||||
_args, _ := msg.Optionv(ice.MSG_ARGS).([]interface{})
|
||||
Render(msg, msg.Option(ice.MSG_OUTPUT), _args...)
|
||||
}
|
||||
func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
|
||||
if r.Header.Get("index.module") == "" {
|
||||
// 解析地址
|
||||
if ip := r.Header.Get("X-Forwarded-For"); ip != "" {
|
||||
r.Header.Set(ice.MSG_USERIP, ip)
|
||||
} else if ip := r.Header.Get("X-Real-Ip"); ip != "" {
|
||||
r.Header.Set(ice.MSG_USERIP, ip)
|
||||
} else if strings.HasPrefix(r.RemoteAddr, "[") {
|
||||
r.Header.Set(ice.MSG_USERIP, strings.Split(r.RemoteAddr, "]")[0][1:])
|
||||
} else {
|
||||
r.Header.Set(ice.MSG_USERIP, strings.Split(r.RemoteAddr, ":")[0])
|
||||
}
|
||||
m.Info("").Info("%s %s %s", r.Header.Get(ice.MSG_USERIP), r.Method, r.URL)
|
||||
func _serve_login(msg *ice.Message, cmds []string, w http.ResponseWriter, r *http.Request) ([]string, bool) {
|
||||
msg.Option(ice.MSG_USERROLE, aaa.VOID)
|
||||
msg.Option(ice.MSG_USERNAME, "")
|
||||
|
||||
r.Header.Set("index.module", m.Target().Name)
|
||||
r.Header.Set("index.path", r.URL.Path)
|
||||
r.Header.Set("index.url", r.URL.String())
|
||||
|
||||
if m.Conf(SERVE, "meta.logheaders") == "true" {
|
||||
// 请求参数
|
||||
for k, v := range r.Header {
|
||||
m.Info("%s: %v", k, kit.Format(v))
|
||||
}
|
||||
m.Info(" ")
|
||||
|
||||
defer func() {
|
||||
// 响应参数
|
||||
for k, v := range w.Header() {
|
||||
m.Info("%s: %v", k, kit.Format(v))
|
||||
}
|
||||
m.Info(" ")
|
||||
}()
|
||||
}
|
||||
|
||||
if r.URL.Path == "/" && strings.Contains(r.Header.Get("User-Agent"), "curl") {
|
||||
http.ServeFile(w, r, path.Join(m.Conf(SERVE, "meta.intshell.path"), m.Conf(SERVE, "meta.intshell.index")))
|
||||
return false
|
||||
}
|
||||
if msg.Options(ice.MSG_SESSID) {
|
||||
// 会话认证
|
||||
aaa.SessCheck(msg, msg.Option(ice.MSG_SESSID))
|
||||
}
|
||||
|
||||
if strings.HasPrefix(r.URL.Path, "/debug") {
|
||||
r.URL.Path = strings.Replace(r.URL.Path, "/debug", "/code", -1)
|
||||
if !msg.Options(ice.MSG_USERNAME) && tcp.IsLocalHost(msg, msg.Option(ice.MSG_USERIP)) {
|
||||
// 自动认证
|
||||
aaa.UserLogin(msg, ice.Info.UserName, ice.Info.PassWord)
|
||||
}
|
||||
|
||||
if r.URL.Path == "/" && m.Conf(SERVE, "meta.sso") != "" {
|
||||
if r.ParseForm(); r.FormValue(ice.MSG_SESSID) != "" {
|
||||
return true
|
||||
}
|
||||
if _, ok := msg.Target().Commands[LOGIN]; ok {
|
||||
// 权限检查
|
||||
msg.Target().Cmd(msg, LOGIN, msg.Option(ice.MSG_USERURL), cmds...)
|
||||
cmds = kit.Simple(msg.Optionv(ice.MSG_CMDS))
|
||||
|
||||
sessid := ""
|
||||
if c, e := r.Cookie(ice.MSG_SESSID); e == nil {
|
||||
m.Richs("aaa.sess", "", c.Value, func(key string, value map[string]interface{}) {
|
||||
sessid = c.Value
|
||||
})
|
||||
}
|
||||
} else if ls := strings.Split(msg.Option(ice.MSG_USERURL), "/"); msg.Conf(SERVE, kit.Keys("meta.black", ls[1])) == "true" {
|
||||
return cmds, false // 白名单
|
||||
|
||||
} else if msg.Conf(SERVE, kit.Keys("meta.white", ls[1])) == "true" {
|
||||
return cmds, true // 黑名单
|
||||
|
||||
if sessid == "" {
|
||||
http.Redirect(w, r, m.Conf(SERVE, "meta.sso"), http.StatusTemporaryRedirect)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else if r.URL.Path == "/share" && r.Method == "GET" {
|
||||
http.ServeFile(w, r, m.Conf(SERVE, "meta.volcanos.share"))
|
||||
} else {
|
||||
if b, ok := ice.BinPack[r.URL.Path]; ok {
|
||||
log.Info("BinPack %v %v", r.URL.Path, len(b))
|
||||
if strings.HasSuffix(r.URL.Path, ".css") {
|
||||
w.Header().Set("Content-Type", "text/css; charset=utf-8")
|
||||
}
|
||||
w.Write(b)
|
||||
return false
|
||||
if msg.Warn(!msg.Options(ice.MSG_USERNAME), ice.ErrNotLogin, msg.Option(ice.MSG_USERURL)) {
|
||||
msg.Render(STATUS, 401, ice.ErrNotLogin)
|
||||
return cmds, false // 未登录
|
||||
}
|
||||
if msg.Warn(!msg.Right(msg.Option(ice.MSG_USERURL))) {
|
||||
msg.Render(STATUS, 403, ice.ErrNotAuth)
|
||||
return cmds, false // 未授权
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
return cmds, msg.Option(ice.MSG_USERURL) != ""
|
||||
}
|
||||
|
||||
const (
|
||||
LOGIN = "_login"
|
||||
)
|
||||
const (
|
||||
SERVE_START = "serve.start"
|
||||
SERVE_CLOSE = "serve.close"
|
||||
)
|
||||
const SERVE = "serve"
|
||||
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
SERVE: {Name: "serve", Help: "服务器", Value: kit.Data(
|
||||
"logheaders", "false",
|
||||
"black", kit.Dict(),
|
||||
"white", kit.Dict(
|
||||
"header", true,
|
||||
"river", true,
|
||||
"action", true,
|
||||
"footer", true,
|
||||
|
||||
"login", true,
|
||||
"share", true,
|
||||
"space", true,
|
||||
"route", true,
|
||||
"static", true,
|
||||
"plugin", true,
|
||||
"publish", true,
|
||||
SERVE: {Name: SERVE, Help: "服务器", Value: kit.Data(
|
||||
kit.MDB_SHORT, kit.MDB_NAME,
|
||||
"logheaders", "false", "black", kit.Dict(), "white", kit.Dict(
|
||||
"space", true, "share", true, "plugin", true, "publish", true,
|
||||
),
|
||||
|
||||
"intshell", kit.Dict(
|
||||
"index", "index.sh",
|
||||
"path", "usr/intshell", "require", ".ish/pluged",
|
||||
"repos", "https://github.com/shylinux/volcanos", "branch", "master",
|
||||
),
|
||||
"static", kit.Dict("/", "usr/volcanos/"),
|
||||
|
||||
"volcanos", kit.Dict("refresh", "5",
|
||||
"share", "usr/volcanos/page/share.html",
|
||||
@ -263,30 +243,40 @@ func init() {
|
||||
"repos", "https://github.com/shylinux/volcanos", "branch", "master",
|
||||
), "publish", "usr/publish/",
|
||||
|
||||
"static", kit.Dict("/", "usr/volcanos/"),
|
||||
"template", kit.Dict("path", "usr/template", "list", []interface{}{
|
||||
`{{define "raw"}}{{.Result}}{{end}}`,
|
||||
}),
|
||||
"intshell", kit.Dict(
|
||||
"index", "index.sh",
|
||||
"path", "usr/intshell", "require", ".ish/pluged",
|
||||
"repos", "https://github.com/shylinux/volcanos", "branch", "master",
|
||||
),
|
||||
)},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
SERVE: {Name: "serve [random] [ups...]", Help: "服务器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if cli.NodeInfo(m, SERVER, cli.HostName); len(arg) > 0 && arg[0] == "random" {
|
||||
cli.NodeInfo(m, SERVER, cli.PathName)
|
||||
// 随机端口
|
||||
m.Cmd(SPIDE, mdb.CREATE, "self", "http://random")
|
||||
arg = arg[1:]
|
||||
}
|
||||
SERVE: {Name: "serve name auto start", Help: "服务器", Action: map[string]*ice.Action{
|
||||
gdb.START: {Name: "start name=self proto=http host= port=9020 dev=", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
|
||||
if cli.NodeInfo(m, SERVER, ice.Info.HostName); m.Option(tcp.PORT) == "random" {
|
||||
m.Option(tcp.PORT, m.Cmdx(tcp.PORT, aaa.Right))
|
||||
}
|
||||
|
||||
// 启动服务
|
||||
m.Target().Start(m, "self")
|
||||
defer m.Cmd(SPACE, "connect", "self")
|
||||
m.Sleep("1s")
|
||||
m.Target().Start(m, kit.MDB_NAME, m.Option(kit.MDB_NAME), tcp.HOST, m.Option(tcp.HOST), tcp.PORT, m.Option(tcp.PORT))
|
||||
m.Sleep("1s")
|
||||
|
||||
// 连接服务
|
||||
for _, k := range arg {
|
||||
m.Cmd(SPACE, "connect", k)
|
||||
}
|
||||
for _, k := range kit.Split(m.Option(SPIDE_DEV)) {
|
||||
m.Cmd(SPACE, "connect", k)
|
||||
}
|
||||
}},
|
||||
aaa.WHITE: {Name: "white", Help: "白名单", Hand: func(m *ice.Message, arg ...string) {
|
||||
for _, k := range arg {
|
||||
m.Conf(SERVE, kit.Keys(kit.MDB_META, aaa.WHITE, k), true)
|
||||
}
|
||||
}},
|
||||
aaa.BLACK: {Name: "black", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) {
|
||||
for _, k := range arg {
|
||||
m.Conf(SERVE, kit.Keys(kit.MDB_META, aaa.BLACK, k), true)
|
||||
}
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Option(mdb.FIELDS, kit.Select("time,status,name,port,dev", mdb.DETAIL, len(arg) > 0))
|
||||
m.Cmdy(mdb.SELECT, SERVE, "", mdb.HASH, kit.MDB_NAME, arg)
|
||||
}},
|
||||
}}, nil)
|
||||
}
|
||||
|
@ -77,8 +77,8 @@ const SHARE = "share"
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
SHARE: {Name: "share", Help: "共享链", Value: kit.Data(
|
||||
"expire", "72h", "template", share_template,
|
||||
SHARE: {Name: SHARE, Help: "共享链", Value: kit.Data(
|
||||
"expire", "72h",
|
||||
)},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
|
@ -3,11 +3,10 @@ package web
|
||||
import (
|
||||
"github.com/gorilla/websocket"
|
||||
ice "github.com/shylinux/icebergs"
|
||||
aaa "github.com/shylinux/icebergs/base/aaa"
|
||||
"github.com/shylinux/icebergs/base/cli"
|
||||
"github.com/shylinux/icebergs/base/aaa"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
"github.com/shylinux/icebergs/base/tcp"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
"github.com/shylinux/toolkits/task"
|
||||
|
||||
"math/rand"
|
||||
"net"
|
||||
@ -18,54 +17,68 @@ import (
|
||||
)
|
||||
|
||||
func _space_list(m *ice.Message, space string) {
|
||||
m.Option(mdb.FIELDS, "time,type,name,text")
|
||||
m.Option(mdb.FIELDS, kit.Select("time,type,name,text", mdb.DETAIL, space != ""))
|
||||
m.Cmdy(mdb.SELECT, SPACE, "", mdb.HASH, kit.MDB_HASH, space)
|
||||
m.Table(func(index int, value map[string]string, head []string) {
|
||||
m.PushRender(kit.MDB_LINK, "a", kit.Format(value[kit.MDB_NAME]),
|
||||
kit.MergeURL(m.Option(ice.MSG_USERWEB), kit.SSH_POD, kit.Keys(m.Option(kit.SSH_POD), value[kit.MDB_NAME])))
|
||||
if p := kit.MergeURL(m.Option(ice.MSG_USERWEB), kit.SSH_POD, kit.Keys(m.Option(kit.SSH_POD), kit.Select(value[kit.MDB_VALUE], value[kit.MDB_NAME]))); space == "" {
|
||||
m.PushRender(kit.MDB_LINK, "a", value[kit.MDB_NAME], p)
|
||||
} else if value[kit.MDB_KEY] == kit.MDB_NAME {
|
||||
m.Push(kit.MDB_KEY, kit.MDB_LINK)
|
||||
m.PushRender(kit.MDB_VALUE, "a", value[kit.MDB_VALUE], p)
|
||||
}
|
||||
})
|
||||
m.Sort(kit.MDB_NAME)
|
||||
}
|
||||
func _space_dial(m *ice.Message, dev, name string, arg ...string) {
|
||||
m.Debug("what %v %v %v", dev, name, arg)
|
||||
m.Richs(SPIDE, nil, dev, func(key string, value map[string]interface{}) {
|
||||
m.Debug("what")
|
||||
client := kit.Value(value, "client").(map[string]interface{})
|
||||
redial := m.Confm(SPACE, "meta.redial")
|
||||
web := m.Target().Server().(*Frame)
|
||||
|
||||
host := kit.Format(client["hostname"])
|
||||
proto := kit.Select("ws", "wss", client["protocol"] == "https")
|
||||
uri := kit.MergeURL(proto+"://"+host+"/space/", "name", name, "type", cli.NodeType, "share", os.Getenv("ctx_share"), "river", os.Getenv("ctx_river"))
|
||||
uri := kit.MergeURL(proto+"://"+host+"/space/", "name", name, "type", ice.Info.NodeType, "share", os.Getenv("ctx_share"), "river", os.Getenv("ctx_river"))
|
||||
if u, e := url.Parse(uri); m.Assert(e) {
|
||||
m.Debug("what")
|
||||
|
||||
task.Put(dev, func(task *task.Task) error {
|
||||
for i := 0; i < kit.Int(redial["c"]); i++ {
|
||||
if s, e := net.Dial("tcp", host); !m.Warn(e != nil, "%s", e) {
|
||||
if s, _, e := websocket.NewClient(s, u, nil, kit.Int(redial["r"]), kit.Int(redial["w"])); !m.Warn(e != nil, "%s", e) {
|
||||
m.Go(func() {
|
||||
m.Debug("what")
|
||||
for i := 0; i >= 0 && i < kit.Int(redial["c"]); i++ {
|
||||
m.Option(tcp.DIAL_CB, func(s net.Conn, e error) {
|
||||
if m.Warn(e != nil, e) {
|
||||
return
|
||||
}
|
||||
if s, _, e := websocket.NewClient(s, u, nil, kit.Int(redial["r"]), kit.Int(redial["w"])); !m.Warn(e != nil, e) {
|
||||
m.Rich(SPACE, nil, kit.Dict("socket", s, kit.MDB_TYPE, MASTER, kit.MDB_NAME, dev, kit.MDB_TEXT, host))
|
||||
m.Log_CREATE(SPACE, dev, "retry", i, "uri", uri)
|
||||
|
||||
// 连接成功
|
||||
m.Rich(SPACE, nil, kit.Dict("socket", s,
|
||||
kit.MDB_TYPE, MASTER, kit.MDB_NAME, dev, kit.MDB_TEXT, host,
|
||||
))
|
||||
m.Log_CREATE("space", dev, "retry", i, "uri", uri)
|
||||
|
||||
m = m.Spawns()
|
||||
if i = 0; _space_handle(m, true, web.send, s, dev) {
|
||||
// 连接关闭
|
||||
break
|
||||
i = -1 // 连接关闭
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
ls := strings.Split(host, ":")
|
||||
m.Cmd(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, "wss", kit.MDB_NAME, dev, tcp.HOST, ls[0], tcp.PORT, ls[1])
|
||||
|
||||
// 断线重连
|
||||
sleep := time.Duration(rand.Intn(kit.Int(redial["a"])*i+2)+kit.Int(redial["b"])) * time.Millisecond
|
||||
m.Cost("order: %d sleep: %s reconnect: %s", i, sleep, u)
|
||||
m.Cost("order", i, "sleep", sleep, "reconnect", u)
|
||||
time.Sleep(sleep)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
func _space_send(m *ice.Message, space string, arg ...string) {
|
||||
if space == "" || space == MYSELF || space == ice.Info.NodeName {
|
||||
m.Cmdy(arg)
|
||||
return // 本地命令
|
||||
}
|
||||
|
||||
target := strings.Split(space, ".")
|
||||
frame := m.Target().Server().(*Frame)
|
||||
m.Warn(m.Richs(SPACE, nil, target[0], func(key string, value map[string]interface{}) {
|
||||
@ -93,7 +106,7 @@ func _space_send(m *ice.Message, space string, arg ...string) {
|
||||
m.Call(m.Option("_async") == "", func(res *ice.Message) *ice.Message {
|
||||
if delete(frame.send, id); res != nil && m != nil {
|
||||
// 返回结果
|
||||
return m.Cost("[%v]->%v %v %v", id, target, arg, m.Copy(res).Format("append"))
|
||||
return m.Cost(kit.Format("[%v]->%v %v %v", id, target, arg, m.Copy(res).Format(ice.MSG_APPEND)))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@ -115,7 +128,7 @@ func _space_exec(msg *ice.Message, source, target []string, c *websocket.Conn, n
|
||||
}
|
||||
msg.Set("_option")
|
||||
_space_echo(msg, []string{}, kit.Revert(source)[1:], c, name)
|
||||
msg.Cost("%v->%v %v %v", source, target, msg.Detailv(), msg.Format("append"))
|
||||
msg.Cost(kit.Format("%v->%v %v %v", source, target, msg.Detailv(), msg.Format(ice.MSG_APPEND)))
|
||||
}
|
||||
func _space_handle(m *ice.Message, safe bool, send map[string]*ice.Message, c *websocket.Conn, name string) bool {
|
||||
for running := true; running; {
|
||||
@ -138,10 +151,7 @@ func _space_handle(m *ice.Message, safe bool, send map[string]*ice.Message, c *w
|
||||
if msg.Optionv(ice.MSG_HANDLE, "true"); !msg.Warn(!safe, ice.ErrNotAuth) {
|
||||
// 本地执行
|
||||
msg.Option("_dev", name)
|
||||
task.Put(nil, func(task *task.Task) error {
|
||||
_space_exec(msg, source, target, c, name)
|
||||
return nil
|
||||
})
|
||||
msg.Go(func() { _space_exec(msg, source, target, c, name) })
|
||||
continue
|
||||
}
|
||||
} else if msg.Richs(SPACE, nil, target[0], func(key string, value map[string]interface{}) {
|
||||
@ -176,20 +186,6 @@ func _space_handle(m *ice.Message, safe bool, send map[string]*ice.Message, c *w
|
||||
return false
|
||||
}
|
||||
|
||||
func _space_search(m *ice.Message, kind, name, text string, arg ...string) {
|
||||
m.Richs(SPACE, nil, kit.Select(kit.MDB_FOREACH, name), func(key string, value map[string]interface{}) {
|
||||
if name != "" && name != value[kit.MDB_NAME] && !strings.Contains(kit.Format(value[kit.MDB_TEXT]), name) {
|
||||
return
|
||||
}
|
||||
m.Push("pod", m.Option("pod"))
|
||||
m.Push("ctx", "web")
|
||||
m.Push("cmd", SPACE)
|
||||
m.Push(key, value, []string{kit.MDB_TIME})
|
||||
m.Push(kit.MDB_SIZE, kit.FmtSize(int64(len(kit.Format(value[kit.MDB_TEXT])))))
|
||||
m.Push(key, value, []string{kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT})
|
||||
})
|
||||
}
|
||||
|
||||
const (
|
||||
MASTER = "master"
|
||||
MYSELF = "myself"
|
||||
@ -201,7 +197,7 @@ const (
|
||||
|
||||
const (
|
||||
SPACE_START = "space.start"
|
||||
SPACE_CLOSE = "space.close"
|
||||
SPACE_STOP = "space.stop"
|
||||
)
|
||||
const SPACE = "space"
|
||||
|
||||
@ -215,24 +211,14 @@ func init() {
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
SPACE: {Name: "space name cmd auto", Help: "空间站", Action: map[string]*ice.Action{
|
||||
"connect": {Name: "connect [dev [name]]", Help: "连接", Hand: func(m *ice.Message, arg ...string) {
|
||||
_space_dial(m, kit.Select("dev", arg, 0), kit.Select(cli.NodeName, arg, 2))
|
||||
}},
|
||||
mdb.SEARCH: {Name: "search type name text", Help: "搜索", Hand: func(m *ice.Message, arg ...string) {
|
||||
_space_search(m, arg[0], arg[1], arg[2], arg[3:]...)
|
||||
"connect": {Name: "connect dev name", Help: "连接", Hand: func(m *ice.Message, arg ...string) {
|
||||
_space_dial(m, arg[0], kit.Select(ice.Info.NodeName, arg[1]))
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) < 2 {
|
||||
_space_list(m, kit.Select("", arg, 0))
|
||||
return
|
||||
}
|
||||
|
||||
if arg[0] == "" || arg[0] == MYSELF || arg[0] == cli.NodeName {
|
||||
// 本地命令
|
||||
m.Cmdy(arg[1:])
|
||||
return
|
||||
}
|
||||
|
||||
_space_send(m, arg[0], arg[1:]...)
|
||||
}},
|
||||
|
||||
@ -247,23 +233,21 @@ func init() {
|
||||
h := m.Rich(SPACE, nil, kit.Dict("socket", s, "share", share, "river", river,
|
||||
kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, s.RemoteAddr().String(),
|
||||
))
|
||||
m.Log_CREATE(SPACE, name)
|
||||
|
||||
task.Put(name, func(task *task.Task) error {
|
||||
m.Go(func() {
|
||||
// 监听消息
|
||||
switch kind {
|
||||
case WORKER:
|
||||
m.Event(DREAM_START, name)
|
||||
defer m.Event(DREAM_STOP, name)
|
||||
m.Event(DREAM_START, "type", kind, "name", name, "share", share, "river", river)
|
||||
defer m.Event(DREAM_STOP, "type", kind, "name", name, "share", share, "river", river)
|
||||
default:
|
||||
m.Event(SPACE_START, "type", kind, "name", name, "share", share, "river", river)
|
||||
defer m.Event(SPACE_CLOSE, "type", kind, "name", name, "share", share, "river", river)
|
||||
defer m.Event(SPACE_STOP, "type", kind, "name", name, "share", share, "river", river)
|
||||
}
|
||||
|
||||
frame := m.Target().Server().(*Frame)
|
||||
_space_handle(m, false, frame.send, s, name)
|
||||
m.Log(ice.LOG_CLOSE, "%s: %s", name, kit.Format(m.Confv(SPACE, kit.Keys(kit.MDB_HASH, h))))
|
||||
m.Confv(SPACE, kit.Keys(kit.MDB_HASH, h), "")
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}},
|
||||
|
@ -2,15 +2,12 @@ package web
|
||||
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/aaa"
|
||||
"github.com/shylinux/icebergs/base/cli"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
"github.com/shylinux/icebergs/base/tcp"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
@ -22,96 +19,33 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func _spide_list(m *ice.Message, name string) {
|
||||
if name == "" {
|
||||
m.Richs(SPIDE, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
|
||||
m.Push(key, value["client"], []string{"name", "share", "login", "method", "url"})
|
||||
})
|
||||
m.Sort("name")
|
||||
return
|
||||
}
|
||||
|
||||
m.Richs(SPIDE, nil, name, func(key string, value map[string]interface{}) {
|
||||
m.Push("detail", value)
|
||||
if kit.Value(value, "client.share") != nil {
|
||||
m.Push("key", "share")
|
||||
m.Push("value", fmt.Sprintf(m.Conf(SHARE, "meta.template.text"), m.Conf(SHARE, "meta.domain"), kit.Value(value, "client.share")))
|
||||
}
|
||||
})
|
||||
}
|
||||
func _spide_show(m *ice.Message, name string) {
|
||||
}
|
||||
func _spide_login(m *ice.Message, name string) {
|
||||
m.Richs(SPIDE, nil, name, func(key string, value map[string]interface{}) {
|
||||
msg := m.Cmd(SPIDE, name, "msg", "/route/login", "login")
|
||||
if msg.Append(ice.MSG_USERNAME) != "" {
|
||||
m.Echo(msg.Append(ice.MSG_USERNAME))
|
||||
return
|
||||
}
|
||||
if msg.Result() != "" {
|
||||
kit.Value(value, "client.login", msg.Result())
|
||||
kit.Value(value, "client.share", m.Cmdx(SHARE, SPIDE, name,
|
||||
kit.Format("%s?sessid=%s", kit.Value(value, "client.url"), kit.Value(value, "cookie.sessid"))))
|
||||
}
|
||||
m.Render(ice.RENDER_QRCODE, kit.Dict(
|
||||
kit.MDB_TYPE, "login", kit.MDB_NAME, name,
|
||||
kit.MDB_TEXT, kit.Value(value, "cookie.sessid"),
|
||||
))
|
||||
})
|
||||
}
|
||||
func _spide_create(m *ice.Message, name, address string, arg ...string) {
|
||||
func _spide_create(m *ice.Message, name, address string) {
|
||||
if uri, e := url.Parse(address); e == nil && address != "" {
|
||||
if uri.Host == "random" {
|
||||
uri.Host = ":" + m.Cmdx(tcp.PORT, aaa.Right)
|
||||
address = strings.Replace(address, "random", uri.Host, -1)
|
||||
}
|
||||
|
||||
if m.Richs(SPIDE, nil, name, func(key string, value map[string]interface{}) {
|
||||
kit.Value(value, "client.hostname", uri.Host)
|
||||
kit.Value(value, "client.url", address)
|
||||
}) == nil {
|
||||
dir, file := path.Split(uri.EscapedPath())
|
||||
m.Rich(SPIDE, nil, kit.Dict(
|
||||
m.Echo(m.Rich(SPIDE, nil, kit.Dict(
|
||||
"cookie", kit.Dict(), "header", kit.Dict(), "client", kit.Dict(
|
||||
// "share", ShareCreate(m.Spawn(), SPIDE, name, address),
|
||||
"name", name, "url", address, "method", "POST",
|
||||
"name", name, "url", address, "method", SPIDE_POST,
|
||||
"protocol", uri.Scheme, "hostname", uri.Host,
|
||||
"path", dir, "file", file, "query", uri.RawQuery,
|
||||
"timeout", "600s", "logheaders", false,
|
||||
),
|
||||
))
|
||||
)))
|
||||
}
|
||||
m.Log_CREATE(SPIDE, name, "address", address)
|
||||
m.Log_CREATE(SPIDE, name, ADDRESS, address)
|
||||
}
|
||||
}
|
||||
func _spide_search(m *ice.Message, kind, name, text string, arg ...string) {
|
||||
m.Richs(SPIDE, nil, kit.Select(kit.MDB_FOREACH, ""), func(key string, value map[string]interface{}) {
|
||||
if kit.Format(kit.Value(value, "client.name")) != name && (text == "" || !strings.Contains(kit.Format(kit.Value(value, "client.url")), text)) {
|
||||
return
|
||||
}
|
||||
|
||||
m.Push("pod", m.Option("pod"))
|
||||
m.Push("ctx", "web")
|
||||
m.Push("cmd", SPIDE)
|
||||
m.Push(key, value, []string{kit.MDB_TIME})
|
||||
m.Push(kit.MDB_SIZE, 0)
|
||||
m.Push("type", SPIDE)
|
||||
// m.Push("type", kit.Format(kit.Value(value, "client.protocol")))
|
||||
m.Push("name", kit.Format(kit.Value(value, "client.name")))
|
||||
m.Push("text", kit.Format(kit.Value(value, "client.url")))
|
||||
})
|
||||
}
|
||||
func _spide_render(m *ice.Message, kind, name, text string, arg ...string) {
|
||||
m.Echo(`<iframe src="%s" width=800 height=400></iframe>`, text)
|
||||
}
|
||||
|
||||
const (
|
||||
SPIDE_SHY = "shy"
|
||||
SPIDE_DEV = "dev"
|
||||
SPIDE_SELF = "self"
|
||||
|
||||
SPIDE_MSG = "msg"
|
||||
SPIDE_RAW = "raw"
|
||||
SPIDE_MSG = "msg"
|
||||
SPIDE_SAVE = "save"
|
||||
SPIDE_CACHE = "cache"
|
||||
|
||||
@ -120,11 +54,12 @@ const (
|
||||
SPIDE_POST = "POST"
|
||||
SPIDE_DELETE = "DELETE"
|
||||
|
||||
SPIDE_FILE = "file"
|
||||
SPIDE_DATA = "data"
|
||||
SPIDE_PART = "part"
|
||||
SPIDE_FORM = "form"
|
||||
SPIDE_PART = "part"
|
||||
SPIDE_JSON = "json"
|
||||
SPIDE_DATA = "data"
|
||||
SPIDE_FILE = "file"
|
||||
SPIDE_BODY = "body"
|
||||
|
||||
SPIDE_CLIENT = "client"
|
||||
SPIDE_HEADER = "header"
|
||||
@ -137,42 +72,39 @@ const (
|
||||
ContentJSON = "application/json"
|
||||
ContentHTML = "text/html"
|
||||
)
|
||||
|
||||
const (
|
||||
ADDRESS = "address"
|
||||
REQUEST = "request"
|
||||
RESPONSE = "response"
|
||||
PROTOCOL = "protocol"
|
||||
)
|
||||
const SPIDE = "spide"
|
||||
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
SPIDE: {Name: "spide", Help: "蜘蛛侠", Value: kit.Data(kit.MDB_SHORT, "client.name")},
|
||||
|
||||
"spide_rewrite": {Name: "spide_rewrite", Help: "重定向", Value: kit.Data(kit.MDB_SHORT, "from")},
|
||||
SPIDE: {Name: SPIDE, Help: "蜘蛛侠", Value: kit.Data(kit.MDB_SHORT, "client.name")},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
"spide_rewrite": {Name: "spide name=auto [action:select=msg|raw|cache] [method:select=POST|GET] url [format:select=json|form|part|data|file] arg... auto", Help: "蜘蛛侠", Action: map[string]*ice.Action{
|
||||
mdb.CREATE: {Name: "create from to", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(mdb.INSERT, m.Prefix("spide_rewrite"), "", mdb.HASH, arg)
|
||||
SPIDE: {Name: "spide client.name action=raw,msg,save,cache method=GET,PUT,POST,DELETE url format=form,part,json,data,file arg auto 创建", Help: "蜘蛛侠", Action: map[string]*ice.Action{
|
||||
mdb.CREATE: {Name: "create name address", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||
if arg[0] != "name" {
|
||||
m.Option("name", arg[0])
|
||||
m.Option(ADDRESS, arg[1])
|
||||
}
|
||||
_spide_create(m, m.Option(kit.MDB_NAME), m.Option(ADDRESS))
|
||||
}},
|
||||
mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(mdb.MODIFY, SPIDE, "", mdb.HASH, "client.name", m.Option("client.name"), arg)
|
||||
}},
|
||||
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, "client.name", m.Option("client.name"))
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Option(mdb.FIELDS, "time,hash,from,to")
|
||||
m.Cmdy(mdb.SELECT, m.Prefix("spide_rewrite"), "", mdb.HASH, "from", arg)
|
||||
}},
|
||||
|
||||
SPIDE: {Name: "spide name=auto [action:select=msg|raw|save|cache] [method:select=POST|GET] url [format:select=json|form|part|data|file] arg... auto", Help: "蜘蛛侠", Action: map[string]*ice.Action{
|
||||
mdb.CREATE: {Name: "create name address", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
|
||||
_spide_create(m, arg[0], arg[1])
|
||||
}},
|
||||
mdb.SEARCH: {Name: "search type name text arg...", Help: "搜索", Hand: func(m *ice.Message, arg ...string) {
|
||||
_spide_search(m, arg[0], arg[1], arg[2], arg[3:]...)
|
||||
}},
|
||||
mdb.RENDER: {Name: "render type name text arg...", Help: "渲染", Hand: func(m *ice.Message, arg ...string) {
|
||||
_spide_render(m, arg[0], arg[1], arg[2], arg[3:]...)
|
||||
}},
|
||||
"login": {Name: "login name", Help: "", Hand: func(m *ice.Message, arg ...string) {
|
||||
_spide_login(m, arg[0])
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) < 2 || len(arg) > 3 && arg[3] == "" {
|
||||
_spide_list(m, kit.Select("", arg, 1))
|
||||
if len(arg) < 2 || arg[0] == "" || (len(arg) > 3 && arg[3] == "") {
|
||||
m.Option(mdb.FIELDS, kit.Select("time,client.name,client.method,client.url", mdb.DETAIL, len(arg) > 0 && arg[0] != ""))
|
||||
m.Cmdy(mdb.SELECT, SPIDE, "", mdb.HASH, "client.name", arg)
|
||||
m.PushAction(mdb.REMOVE)
|
||||
return
|
||||
}
|
||||
|
||||
@ -181,10 +113,10 @@ func init() {
|
||||
// 缓存数据
|
||||
cache, save := "", ""
|
||||
switch arg[1] {
|
||||
case SPIDE_MSG:
|
||||
cache, arg = arg[1], arg[1:]
|
||||
case SPIDE_RAW:
|
||||
cache, arg = arg[1], arg[1:]
|
||||
case SPIDE_MSG:
|
||||
cache, arg = arg[1], arg[1:]
|
||||
case SPIDE_SAVE:
|
||||
cache, save, arg = arg[1], arg[2], arg[2:]
|
||||
case SPIDE_CACHE:
|
||||
@ -207,23 +139,17 @@ func init() {
|
||||
// 请求地址
|
||||
uri, arg := arg[0], arg[1:]
|
||||
if strings.HasPrefix(uri, "ftp") {
|
||||
m.Cmdy(cli.SYSTEM, "wget", uri)
|
||||
m.Cmdy(cli.SYSTEM, "wget", uri, arg)
|
||||
return
|
||||
}
|
||||
// if n := m.Cmd("spide_rewrite", uri).Append("to"); n != "" && n != uri {
|
||||
// m.Logs("rewrite", "from", uri, "to", n)
|
||||
// uri = n
|
||||
// }
|
||||
|
||||
// 渲染引擎
|
||||
head := map[string]string{}
|
||||
body, ok := m.Optionv("body").(io.Reader)
|
||||
body, ok := m.Optionv(SPIDE_BODY).(io.Reader)
|
||||
if !ok && len(arg) > 0 && method != SPIDE_GET {
|
||||
switch arg[0] {
|
||||
case SPIDE_FILE:
|
||||
if f, e := os.Open(arg[1]); m.Warn(e != nil, "%s", e) {
|
||||
return
|
||||
} else {
|
||||
if f, e := os.Open(arg[1]); m.Assert(e) {
|
||||
defer f.Close()
|
||||
body, arg = f, arg[2:]
|
||||
}
|
||||
@ -277,7 +203,7 @@ func init() {
|
||||
head[ContentType] = ContentJSON
|
||||
body = bytes.NewBuffer(b)
|
||||
}
|
||||
m.Log(ice.LOG_EXPORT, "json: %s", kit.Format(data))
|
||||
m.Log_EXPORT(SPIDE_JSON, kit.Format(data))
|
||||
}
|
||||
arg = arg[:0]
|
||||
} else {
|
||||
@ -291,13 +217,13 @@ func init() {
|
||||
m.Assert(e)
|
||||
|
||||
// 请求变量
|
||||
kit.Fetch(value[SPIDE_HEADER], func(key string, value string) {
|
||||
req.Header.Set(key, value)
|
||||
})
|
||||
kit.Fetch(value[SPIDE_COOKIE], func(key string, value string) {
|
||||
req.AddCookie(&http.Cookie{Name: key, Value: value})
|
||||
m.Info("%s: %s", key, value)
|
||||
})
|
||||
kit.Fetch(value[SPIDE_HEADER], func(key string, value string) {
|
||||
req.Header.Set(key, value)
|
||||
})
|
||||
list := kit.Simple(m.Optionv(SPIDE_HEADER))
|
||||
for i := 0; i < len(list)-1; i += 2 {
|
||||
req.Header.Set(list[i], list[i+1])
|
||||
@ -323,7 +249,8 @@ func init() {
|
||||
}
|
||||
|
||||
// 检查结果
|
||||
m.Cost("%s %s: %s", res.Status, res.Header.Get(ContentLength), res.Header.Get(ContentType))
|
||||
defer res.Body.Close()
|
||||
m.Cost("status", res.Status, "length", res.Header.Get(ContentLength), "type", res.Header.Get(ContentType))
|
||||
if m.Warn(res.StatusCode != http.StatusOK, res.Status) {
|
||||
m.Set(ice.MSG_RESULT)
|
||||
// return
|
||||
@ -335,14 +262,13 @@ func init() {
|
||||
m.Log(ice.LOG_IMPORT, "%s: %s", v.Name, v.Value)
|
||||
}
|
||||
|
||||
defer res.Body.Close()
|
||||
|
||||
// 解析引擎
|
||||
switch cache {
|
||||
case SPIDE_CACHE:
|
||||
m.Optionv("response", res)
|
||||
m.Optionv(RESPONSE, res)
|
||||
m.Cmdy(CACHE, DOWNLOAD, res.Header.Get(ContentType), uri)
|
||||
m.Echo(m.Append(DATA))
|
||||
|
||||
case SPIDE_SAVE:
|
||||
if f, p, e := kit.Create(save); m.Assert(e) {
|
||||
if n, e := io.Copy(f, res.Body); m.Assert(e) {
|
||||
@ -350,10 +276,12 @@ func init() {
|
||||
m.Echo(p)
|
||||
}
|
||||
}
|
||||
|
||||
case SPIDE_RAW:
|
||||
if b, e := ioutil.ReadAll(res.Body); m.Assert(e) {
|
||||
m.Echo(string(b))
|
||||
}
|
||||
|
||||
case SPIDE_MSG:
|
||||
var data map[string][]string
|
||||
m.Assert(json.NewDecoder(res.Body).Decode(&data))
|
||||
@ -364,6 +292,7 @@ func init() {
|
||||
}
|
||||
}
|
||||
m.Resultv(data[ice.MSG_RESULT])
|
||||
|
||||
default:
|
||||
if strings.HasPrefix(res.Header.Get(ContentType), ContentHTML) {
|
||||
b, _ := ioutil.ReadAll(res.Body)
|
||||
|
@ -168,14 +168,14 @@ func init() {
|
||||
)},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
STORY: {Name: "story story=auto key=auto auto", Help: "故事会", Action: map[string]*ice.Action{
|
||||
STORY: {Name: "story story auto", Help: "故事会", Action: map[string]*ice.Action{
|
||||
WRITE: {Name: "write type name text arg...", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||
_story_write(m, arg[0], arg[1], arg[2], arg[3:]...)
|
||||
}},
|
||||
CATCH: {Name: "catch type name arg...", Help: "捕捉", Hand: func(m *ice.Message, arg ...string) {
|
||||
_story_catch(m, arg[0], arg[1], arg[2:]...)
|
||||
}},
|
||||
WATCH: {Name: "watch key name", Help: "查看", Hand: func(m *ice.Message, arg ...string) {
|
||||
WATCH: {Name: "watch key name", Help: "释放", Hand: func(m *ice.Message, arg ...string) {
|
||||
_story_watch(m, arg[0], arg[1])
|
||||
}},
|
||||
INDEX: {Name: "index key", Help: "索引", Hand: func(m *ice.Message, arg ...string) {
|
||||
|
@ -2,9 +2,7 @@ package web
|
||||
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/aaa"
|
||||
"github.com/shylinux/icebergs/base/cli"
|
||||
"github.com/shylinux/icebergs/base/ctx"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
"github.com/shylinux/icebergs/base/tcp"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
@ -12,7 +10,6 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Frame struct {
|
||||
@ -72,57 +69,41 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool {
|
||||
}
|
||||
})
|
||||
|
||||
m.Richs(SPIDE, nil, arg[0], func(key string, value map[string]interface{}) {
|
||||
client := value["client"].(map[string]interface{})
|
||||
web.m, web.Server = m, &http.Server{Handler: web}
|
||||
m.Option(tcp.LISTEN_CB, func(l net.Listener) {
|
||||
m.Cmdy(mdb.INSERT, SERVE, "", mdb.HASH, arg, kit.MDB_STATUS, "start", "proto", m.Option("proto"), "dev", m.Option("dev"))
|
||||
m.Event(SERVE_START, arg...)
|
||||
defer m.Event(SERVE_CLOSE, arg...)
|
||||
defer m.Cmd(mdb.MODIFY, SERVE, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME), kit.MDB_STATUS, "stop")
|
||||
|
||||
web.m, web.Server = m, &http.Server{Handler: web}
|
||||
m.Option(tcp.LISTEN_CB, func(l net.Listener) {
|
||||
m.Event(SERVE_START, arg[0])
|
||||
m.Warn(true, "listen %s", web.Server.Serve(l))
|
||||
m.Event(SERVE_CLOSE, arg[0])
|
||||
})
|
||||
|
||||
ls := strings.Split(m.Cap(ice.CTX_STREAM, client["hostname"]), ":")
|
||||
m.Cmd(tcp.SERVER, tcp.LISTEN, kit.MDB_NAME, "web", tcp.HOST, ls[0], tcp.PORT, ls[1])
|
||||
m.Warn(true, SERVE, ": ", web.Server.Serve(l))
|
||||
})
|
||||
|
||||
m.Cmd(tcp.SERVER, tcp.LISTEN, kit.MDB_TYPE, WEB, kit.MDB_NAME, m.Option(kit.MDB_NAME),
|
||||
tcp.HOST, m.Option(tcp.HOST), tcp.PORT, m.Option(tcp.PORT))
|
||||
return true
|
||||
}
|
||||
func (web *Frame) Close(m *ice.Message, arg ...string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
var Index = &ice.Context{Name: "web", Help: "网络模块",
|
||||
Caches: map[string]*ice.Cache{},
|
||||
Configs: map[string]*ice.Config{},
|
||||
const WEB = "web"
|
||||
|
||||
var Index = &ice.Context{Name: WEB, Help: "网络模块",
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Load()
|
||||
|
||||
m.Cmd(SPIDE, mdb.CREATE, "dev", kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_dev")))
|
||||
m.Cmd(SPIDE, mdb.CREATE, "self", kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_self")))
|
||||
m.Cmd(SPIDE, mdb.CREATE, "shy", kit.Select("https://shylinux.com:443", m.Conf(cli.RUNTIME, "conf.ctx_shy")))
|
||||
|
||||
m.Cmd(aaa.ROLE, aaa.White, aaa.VOID, "web", "/publish/")
|
||||
m.Cmd(aaa.ROLE, aaa.White, aaa.VOID, ctx.COMMAND)
|
||||
|
||||
m.Cmd(mdb.SEARCH, mdb.CREATE, SPIDE)
|
||||
m.Cmd(mdb.RENDER, mdb.CREATE, SPIDE)
|
||||
m.Cmd(mdb.SEARCH, mdb.CREATE, SPACE)
|
||||
|
||||
m.Search("_render", func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) {
|
||||
for k := range cmd.Action {
|
||||
m.Cmd(mdb.RENDER, mdb.CREATE, k, "_render", "web")
|
||||
}
|
||||
})
|
||||
m.Cmd(SPIDE, mdb.CREATE, SPIDE_DEV, kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_dev")))
|
||||
m.Cmd(SPIDE, mdb.CREATE, SPIDE_SELF, kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_self")))
|
||||
m.Cmd(SPIDE, mdb.CREATE, SPIDE_SHY, kit.Select("https://shylinux.com:443", m.Conf(cli.RUNTIME, "conf.ctx_shy")))
|
||||
}},
|
||||
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Save(SPIDE, SERVE, CACHE, SHARE, STORY)
|
||||
m.Save()
|
||||
|
||||
m.Done()
|
||||
m.Richs(SPACE, nil, "*", func(key string, value map[string]interface{}) {
|
||||
if kit.Format(value["type"]) == "master" {
|
||||
m.Done()
|
||||
}
|
||||
m.Done(true)
|
||||
m.Cmd(SERVE).Table(func(index int, value map[string]string, head []string) {
|
||||
m.Done(value[kit.MDB_STATUS] == "start")
|
||||
})
|
||||
}},
|
||||
},
|
||||
@ -130,6 +111,6 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
|
||||
|
||||
func init() {
|
||||
ice.Index.Register(Index, &Frame{},
|
||||
SPIDE, SERVE, SPACE, DREAM, CACHE, SHARE, STORY,
|
||||
SPIDE, SERVE, SPACE, DREAM, ROUTE, SHARE, CACHE, STORY,
|
||||
)
|
||||
}
|
||||
|
13
base/web/web.shy
Normal file
13
base/web/web.shy
Normal file
@ -0,0 +1,13 @@
|
||||
chapter "web"
|
||||
|
||||
field "蜘蛛侠" web.spide
|
||||
field "服务器" web.serve
|
||||
field "空间站" web.space
|
||||
field "梦想家" web.dream
|
||||
|
||||
field "路由器" web.route
|
||||
field "缓存池" web.cache
|
||||
return
|
||||
field "共享链" web.share
|
||||
field "故事会" web.story
|
||||
|
@ -4,9 +4,9 @@ import (
|
||||
"github.com/shylinux/icebergs"
|
||||
)
|
||||
|
||||
var Index = &ice.Context{Name: "yac", Help: "语法模块",
|
||||
Caches: map[string]*ice.Cache{},
|
||||
Configs: map[string]*ice.Config{},
|
||||
const YAC = "yac"
|
||||
|
||||
var Index = &ice.Context{Name: YAC, Help: "语法模块",
|
||||
Commands: map[string]*ice.Command{
|
||||
"hi": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Echo("hello %s world", c.Name)
|
||||
|
@ -2,6 +2,7 @@ package chat
|
||||
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/aaa"
|
||||
"github.com/shylinux/icebergs/base/web"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
)
|
||||
@ -12,6 +13,8 @@ var Index = &ice.Context{Name: CHAT, Help: "聊天中心",
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Load()
|
||||
m.Cmd(web.SERVE, aaa.WHITE, "header", "river", "action", "footer")
|
||||
|
||||
m.Conf(RIVER, "meta.template", kit.Dict(
|
||||
"base", kit.Dict(
|
||||
"info", []interface{}{
|
||||
@ -40,7 +43,7 @@ var Index = &ice.Context{Name: CHAT, Help: "聊天中心",
|
||||
),
|
||||
))
|
||||
m.Watch(web.SPACE_START, m.Prefix(NODE))
|
||||
m.Watch(web.SPACE_CLOSE, m.Prefix(NODE))
|
||||
m.Watch(web.SPACE_STOP, m.Prefix(NODE))
|
||||
}},
|
||||
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save() }},
|
||||
},
|
||||
|
@ -3,7 +3,6 @@ package chat
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
"github.com/shylinux/icebergs/base/web"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"math"
|
||||
@ -59,9 +58,9 @@ func init() {
|
||||
}},
|
||||
|
||||
mdb.RENDER: {Name: "render type name text", Help: "渲染", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(mdb.RENDER, web.RENDER.Frame, kit.Format(
|
||||
"https://map.baidu.com/search/%s/@12958750.085,4825785.55,16z?querytype=s&da_src=shareurl&wd=%s",
|
||||
arg[2], arg[2]))
|
||||
// m.Cmdy(mdb.RENDER, web.RENDER.Frame, kit.Format(
|
||||
// "https://map.baidu.com/search/%s/@12958750.085,4825785.55,16z?querytype=s&da_src=shareurl&wd=%s",
|
||||
// arg[2], arg[2]))
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Option(mdb.FIELDS, "time,type,name,text,longitude,latitude")
|
||||
|
@ -3,10 +3,7 @@ package chat
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
"github.com/shylinux/icebergs/base/web"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"path"
|
||||
)
|
||||
|
||||
const MEET = "meet"
|
||||
@ -93,7 +90,7 @@ func init() {
|
||||
m.Push("照片", "")
|
||||
continue
|
||||
}
|
||||
m.Push("照片", m.Cmdx(mdb.RENDER, web.RENDER.IMG, path.Join("/share/local/usr/image/local/", m.Option(ice.MSG_DOMAIN), value["照片"])))
|
||||
// m.Push("照片", m.Cmdx(mdb.RENDER, web.RENDER.IMG, path.Join("/share/local/usr/image/local/", m.Option(ice.MSG_DOMAIN), value["照片"])))
|
||||
} else {
|
||||
m.Push(k, value[k])
|
||||
}
|
||||
@ -107,7 +104,7 @@ func init() {
|
||||
} else {
|
||||
msg.Table(func(index int, value map[string]string, head []string) {
|
||||
if value["key"] == "照片" {
|
||||
value["value"] = m.Cmdx(mdb.RENDER, web.RENDER.IMG, path.Join("/share/local/usr/image/local/", m.Option(ice.MSG_DOMAIN), value["value"]), "640")
|
||||
// value["value"] = m.Cmdx(mdb.RENDER, web.RENDER.IMG, path.Join("/share/local/usr/image/local/", m.Option(ice.MSG_DOMAIN), value["value"]), "640")
|
||||
}
|
||||
m.Push("key", value["key"])
|
||||
m.Push("value", value["value"])
|
||||
|
@ -109,8 +109,6 @@ func init() {
|
||||
m.Cmdy(mdb.INSERT, RIVER, kit.Keys(kit.MDB_HASH, m.Option(RIVER), NODE), mdb.HASH, arg)
|
||||
}
|
||||
}},
|
||||
web.SPACE_CLOSE: {Name: "close", Help: "关闭", Hand: func(m *ice.Message, arg ...string) {
|
||||
}},
|
||||
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(mdb.DELETE, RIVER, kit.Keys(kit.MDB_HASH, m.Option(RIVER), NODE), mdb.HASH,
|
||||
kit.MDB_NAME, m.Option(kit.MDB_NAME))
|
||||
|
@ -3,7 +3,6 @@ package code
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
"github.com/shylinux/icebergs/base/web"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
"github.com/shylinux/toolkits/util/bench"
|
||||
|
||||
@ -21,7 +20,7 @@ func _bench_list(m *ice.Message, zone string, id string, field ...interface{}) {
|
||||
if zone = kit.Format(kit.Value(val, kit.MDB_ZONE)); id == "" {
|
||||
m.Grows(BENCH, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) {
|
||||
// 查看信息
|
||||
m.Push("操作", m.Cmdx(mdb.RENDER, web.RENDER.Button, "运行"))
|
||||
// m.Push("操作", m.Cmdx(mdb.RENDER, web.RENDER.Button, "运行"))
|
||||
m.Push(zone, value, []string{
|
||||
kit.MDB_ZONE, kit.MDB_ID, kit.MDB_TYPE,
|
||||
kit.MDB_NAME, NCONN, NREQS, kit.MDB_TEXT,
|
||||
@ -33,7 +32,7 @@ func _bench_list(m *ice.Message, zone string, id string, field ...interface{}) {
|
||||
// 查看信息
|
||||
m.Push("detail", value)
|
||||
m.Push(kit.MDB_KEY, "操作")
|
||||
m.Push(kit.MDB_VALUE, m.Cmdx(mdb.RENDER, web.RENDER.Button, "运行"))
|
||||
// m.Push(kit.MDB_VALUE, m.Cmdx(mdb.RENDER, web.RENDER.Button, "运行"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -68,22 +68,48 @@ func init() {
|
||||
})
|
||||
}},
|
||||
"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:
|
||||
if m.Cmdy(cli.SYSTEM, "./configure", "--prefix="+kit.Path(path.Join(p, kit.Select("_install", m.Option("install")))), arg[1:]); m.Append(cli.CMD_CODE) != "0" {
|
||||
m.Option("cache.button", "构建")
|
||||
m.Option("_process", "_follow")
|
||||
if m.Option("cache.hash") != "" {
|
||||
m.Cmdy(cli.OUTPUT, m.Option("cache.hash"))
|
||||
m.Sort(kit.MDB_ID)
|
||||
m.Table(func(index int, value map[string]string, head []string) {
|
||||
m.Option("cache.begin", value[kit.MDB_ID])
|
||||
m.Echo(value[kit.SSH_RES])
|
||||
})
|
||||
if len(m.Resultv()) > 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if m.Cmdy(cli.SYSTEM, "make", "-j8"); m.Append(cli.CMD_CODE) != "0" {
|
||||
if m.Conf(cli.OUTPUT, kit.Keys(kit.MDB_HASH, m.Option("cache.hash"), kit.MDB_META, kit.MDB_STATUS)) == "stop" {
|
||||
m.Echo("stop")
|
||||
}
|
||||
return
|
||||
}
|
||||
m.Cmdy(cli.OUTPUT, mdb.CREATE, kit.MDB_NAME, arg[0])
|
||||
m.Option("cache.hash", m.Result())
|
||||
m.Option("cache.begin", 1)
|
||||
|
||||
m.Cmdy(cli.SYSTEM, "mv", "INSTALL", "INSTALLS")
|
||||
m.Cmdy(cli.SYSTEM, "make", "PREFIX="+kit.Path(path.Join(p, kit.Select("_install", m.Option("install")))), "install")
|
||||
m.Go(func() {
|
||||
defer m.Cmdy(cli.OUTPUT, mdb.MODIFY, kit.MDB_STATUS, cli.Status.Stop)
|
||||
defer m.Option(kit.MDB_HASH, m.Option("cache.hash"))
|
||||
|
||||
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:
|
||||
if m.Cmdy(cli.SYSTEM, "./configure", "--prefix="+kit.Path(path.Join(p, kit.Select("_install", m.Option("install")))), arg[1:]); m.Append(cli.CMD_CODE) != "0" {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if m.Cmdy(cli.SYSTEM, "make", "-j8"); m.Append(cli.CMD_CODE) != "0" {
|
||||
return
|
||||
}
|
||||
|
||||
m.Cmdy(cli.SYSTEM, "make", "PREFIX="+kit.Path(path.Join(p, kit.Select("_install", m.Option("install")))), "install")
|
||||
})
|
||||
}},
|
||||
"spawn": {Name: "spawn link", Help: "新建", Hand: func(m *ice.Message, arg ...string) {
|
||||
port := m.Cmdx(tcp.PORT, aaa.Right)
|
||||
@ -116,6 +142,17 @@ func init() {
|
||||
return
|
||||
}
|
||||
|
||||
if len(arg) == 1 {
|
||||
// 服务列表
|
||||
m.Option(mdb.FIELDS, "time,port,status,pid,cmd,dir")
|
||||
m.Cmdy(mdb.SELECT, cli.DAEMON, "", mdb.HASH)
|
||||
m.Appendv("port", []string{})
|
||||
m.Table(func(index int, value map[string]string, head []string) {
|
||||
m.Push(kit.SSH_PORT, path.Base(value[kit.SSH_DIR]))
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
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))
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"github.com/shylinux/icebergs/base/cli"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
"github.com/shylinux/icebergs/base/nfs"
|
||||
"github.com/shylinux/icebergs/base/web"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"bufio"
|
||||
@ -127,7 +126,7 @@ func init() {
|
||||
|
||||
if len(arg) == 0 {
|
||||
m.Cmdy(nfs.DIR, WEBPACK).Table(func(index int, value map[string]string, head []string) {
|
||||
m.Push(kit.MDB_LINK, m.Cmdx(mdb.RENDER, web.RENDER.Download, "/publish/"+value[kit.MDB_PATH]))
|
||||
// m.Push(kit.MDB_LINK, m.Cmdx(mdb.RENDER, web.RENDER.Download, "/publish/"+value[kit.MDB_PATH]))
|
||||
})
|
||||
return
|
||||
}
|
||||
@ -168,7 +167,7 @@ func init() {
|
||||
m.Option(nfs.DIR_DEEP, true)
|
||||
|
||||
m.Cmdy(nfs.DIR, BINPACK).Table(func(index int, value map[string]string, head []string) {
|
||||
m.Push(kit.MDB_LINK, m.Cmdx(mdb.RENDER, web.RENDER.Download, "/publish/"+value[kit.MDB_PATH]))
|
||||
// m.Push(kit.MDB_LINK, m.Cmdx(mdb.RENDER, web.RENDER.Download, "/publish/"+value[kit.MDB_PATH]))
|
||||
})
|
||||
}},
|
||||
MODPACK: {Name: "modpack path=auto auto 创建", Help: "打包", Meta: kit.Dict(
|
||||
|
@ -3,7 +3,6 @@ package code
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
"github.com/shylinux/icebergs/base/web"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"net/http"
|
||||
@ -17,7 +16,7 @@ func _pprof_list(m *ice.Message, zone string, id string, field ...interface{}) {
|
||||
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.Push("操作", m.Cmdx(mdb.RENDER, web.RENDER.Button, "运行"))
|
||||
// m.Push("操作", m.Cmdx(mdb.RENDER, web.RENDER.Button, "运行"))
|
||||
m.Push(zone, value, []string{
|
||||
kit.MDB_ZONE, kit.MDB_ID, kit.MDB_TYPE,
|
||||
kit.MDB_NAME, kit.MDB_TEXT, SECONDS, BINNARY, SERVICE,
|
||||
@ -28,7 +27,7 @@ func _pprof_list(m *ice.Message, zone string, id string, field ...interface{}) {
|
||||
// 详细信息
|
||||
m.Push("detail", value)
|
||||
m.Push(kit.MDB_KEY, "操作")
|
||||
m.Push(kit.MDB_VALUE, m.Cmdx(mdb.RENDER, web.RENDER.Button, "运行"))
|
||||
// m.Push(kit.MDB_VALUE, m.Cmdx(mdb.RENDER, web.RENDER.Button, "运行"))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/cli"
|
||||
"github.com/shylinux/icebergs/base/ctx"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
"github.com/shylinux/icebergs/base/nfs"
|
||||
"github.com/shylinux/icebergs/base/ssh"
|
||||
"github.com/shylinux/icebergs/base/web"
|
||||
@ -284,11 +283,12 @@ func _video_show(m *ice.Message, name, text string, arg ...string) {
|
||||
}
|
||||
func _baidu_show(m *ice.Message, name, text string, arg ...string) {
|
||||
_option(m, BAIDU, name, text, arg...)
|
||||
m.Cmdy(mdb.RENDER, web.RENDER.Frame, kit.Format("https://baidu.com/s?wd=%s", text))
|
||||
|
||||
// m.Cmdy(mdb.RENDER, web.RENDER.Frame, kit.Format("https://baidu.com/s?wd=%s", text))
|
||||
}
|
||||
func _other_show(m *ice.Message, name, text string, arg ...string) {
|
||||
_option(m, OTHER, name, text, arg...)
|
||||
m.Cmdy(mdb.RENDER, web.RENDER.Frame, text)
|
||||
// m.Cmdy(mdb.RENDER, web.RENDER.Frame, text)
|
||||
}
|
||||
|
||||
func _word_show(m *ice.Message, name string, arg ...string) {
|
||||
@ -383,7 +383,7 @@ func init() {
|
||||
Commands: map[string]*ice.Command{
|
||||
TITLE: {Name: "title [premenu|chapter|section|endmenu] text", Help: "标题", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
ns := strings.Split(cli.NodeName, "-")
|
||||
ns := strings.Split(ice.Info.NodeName, "-")
|
||||
arg = append(arg, kit.Select(ns[len(ns)-1], ""))
|
||||
}
|
||||
|
||||
|
7
exec.go
7
exec.go
@ -66,7 +66,10 @@ func (m *Message) Hold(n int) *Message {
|
||||
m.Log(LOG_TRACE, "%s wait %s %v", ctx.Name, m.target.Name, ctx.wg)
|
||||
return m
|
||||
}
|
||||
func (m *Message) Done() bool {
|
||||
func (m *Message) Done(b bool) bool {
|
||||
if !b {
|
||||
return false
|
||||
}
|
||||
defer func() { recover() }()
|
||||
|
||||
ctx := m.target.root
|
||||
@ -127,7 +130,7 @@ func (m *Message) Gos(msg *Message, cb interface{}, args ...interface{}) *Messag
|
||||
msg.Cmdx("gdb.routine", "modify", "status", "stop")
|
||||
return nil
|
||||
})
|
||||
return m
|
||||
return msg
|
||||
}
|
||||
func (m *Message) Go(cb interface{}, args ...interface{}) *Message {
|
||||
switch cb := cb.(type) {
|
||||
|
1
go.sum
1
go.sum
@ -4,6 +4,7 @@ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
|
||||
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/maruel/rs v0.0.0-20150922171536-2c81c4312fe4/go.mod h1:kcRFpEzolcEklV6rD7W95mG49/sbdX/PlFmd7ni3RvA=
|
||||
github.com/nareix/joy4 v0.0.0-20200507095837-05a4ffbb5369 h1:Yp0zFEufLz0H7jzffb4UPXijavlyqlYeOg7dcyVUNnQ=
|
||||
github.com/nareix/joy4 v0.0.0-20200507095837-05a4ffbb5369/go.mod h1:aFJ1ZwLjvHN4yEzE5Bkz8rD8/d8Vlj3UIuvz2yfET7I=
|
||||
github.com/shylinux/toolkits v0.1.8 h1:Lh5HkR1aRzhOOVu9eHwZ5y7dfW7hcFy29IR5tQ5qUeM=
|
||||
github.com/shylinux/toolkits v0.1.8/go.mod h1:Y68Ot6xOmo1bun67YvqC3chDGeU2gDxtsUnvVDGJm4g=
|
||||
|
16
init.go
16
init.go
@ -9,6 +9,22 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var Info = struct {
|
||||
HostName string
|
||||
PathName string
|
||||
UserName string
|
||||
PassWord string
|
||||
NodeName string
|
||||
NodeType string
|
||||
|
||||
Build struct {
|
||||
Time string
|
||||
Version string
|
||||
HostName string
|
||||
UserName string
|
||||
}
|
||||
}{}
|
||||
|
||||
type Frame struct{ code int }
|
||||
|
||||
func (f *Frame) Spawn(m *Message, c *Context, arg ...string) Server {
|
||||
|
12
logs.go
12
logs.go
@ -81,8 +81,16 @@ func (m *Message) Log(level string, str string, arg ...interface{}) *Message {
|
||||
func (m *Message) Info(str string, arg ...interface{}) *Message {
|
||||
return m.log(LOG_INFO, str, arg...)
|
||||
}
|
||||
func (m *Message) Cost(str string, arg ...interface{}) *Message {
|
||||
return m.log(LOG_COST, "%s: %s", m.Format("cost"), kit.Format(str, arg...))
|
||||
func (m *Message) Cost(arg ...interface{}) *Message {
|
||||
list := []string{m.Format("cost")}
|
||||
for i := 0; i < len(arg); i += 2 {
|
||||
if i == len(arg)-1 {
|
||||
list = append(list, kit.Format(arg[i]))
|
||||
} else {
|
||||
list = append(list, kit.Format(arg[i])+":", kit.Format(arg[i+1]))
|
||||
}
|
||||
}
|
||||
return m.log(LOG_COST, strings.Join(list, " "))
|
||||
}
|
||||
func (m *Message) Warn(err bool, arg ...interface{}) bool {
|
||||
if err {
|
||||
|
33
meta.go
33
meta.go
@ -63,19 +63,14 @@ func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Messa
|
||||
for _, k := range head {
|
||||
m.Push(k, value[k])
|
||||
}
|
||||
return m
|
||||
case map[string]interface{}:
|
||||
if key == "detail" {
|
||||
// 格式转换
|
||||
value = kit.KeyValue(map[string]interface{}{}, "", value)
|
||||
}
|
||||
|
||||
case map[string]interface{}:
|
||||
// 键值排序
|
||||
list := []string{}
|
||||
if len(arg) > 0 {
|
||||
list = kit.Simple(arg[0])
|
||||
} else {
|
||||
for k := range value {
|
||||
for k := range kit.KeyValue(map[string]interface{}{}, "", value) {
|
||||
list = append(list, k)
|
||||
}
|
||||
sort.Strings(list)
|
||||
@ -90,13 +85,6 @@ func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Messa
|
||||
// 查找数据
|
||||
var v interface{}
|
||||
switch k {
|
||||
case "action":
|
||||
list := []string{}
|
||||
for _, k := range kit.Simple(m.Optionv(MSG_ACTION)) {
|
||||
list = append(list, fmt.Sprintf(`<input type="button" value="%s">`, k))
|
||||
}
|
||||
v = strings.Join(list, "")
|
||||
|
||||
case kit.MDB_KEY, kit.MDB_HASH:
|
||||
if key != "" {
|
||||
v = key
|
||||
@ -104,12 +92,12 @@ func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Messa
|
||||
}
|
||||
fallthrough
|
||||
default:
|
||||
if v = value[k]; v == nil {
|
||||
v = value["extra."+k]
|
||||
if v = kit.Value(value, k); v == nil {
|
||||
v = kit.Value(value, kit.Keys(kit.MDB_EXTRA, k))
|
||||
}
|
||||
if v == nil {
|
||||
if v = val[k]; v == nil {
|
||||
v = val["extra."+k]
|
||||
if v = kit.Value(val, k); v == nil {
|
||||
v = kit.Value(val, kit.Keys(kit.MDB_EXTRA, k))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -123,12 +111,13 @@ func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Messa
|
||||
m.Add(MSG_APPEND, k, v)
|
||||
}
|
||||
}
|
||||
return m
|
||||
|
||||
default:
|
||||
for _, v := range kit.Simple(value) {
|
||||
m.Add(MSG_APPEND, key, v)
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range kit.Simple(value) {
|
||||
m.Add(MSG_APPEND, key, v)
|
||||
}
|
||||
return m
|
||||
}
|
||||
func (m *Message) Echo(str string, arg ...interface{}) *Message {
|
||||
|
3
misc.go
3
misc.go
@ -109,8 +109,5 @@ func (m *Message) PushPlugin(key string, arg ...string) *Message {
|
||||
m.Cmdy("command", key)
|
||||
return m
|
||||
}
|
||||
func (m *Message) PushDetail(value interface{}, arg ...interface{}) *Message {
|
||||
return m.Push("detail", value, arg...)
|
||||
}
|
||||
|
||||
var BinPack = map[string][]byte{}
|
||||
|
@ -37,21 +37,21 @@ func init() {
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
REPOS: {Name: "repos name=auto path=auto auto 添加", Help: "代码库", Action: map[string]*ice.Action{
|
||||
mdb.CREATE: {Name: `create remote branch name path`, Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Option("name", kit.Select(strings.TrimSuffix(path.Base(m.Option("remote")), ".git"), m.Option("name")))
|
||||
mdb.CREATE: {Name: `create repos branch name path`, Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Option("name", kit.Select(strings.TrimSuffix(path.Base(m.Option("repos")), ".git"), m.Option("name")))
|
||||
m.Option("path", kit.Select(path.Join("usr", m.Option("name")), m.Option("path")))
|
||||
m.Option("remote", kit.Select(m.Conf(REPOS, "meta.owner")+"/"+m.Option("name"), m.Option("remote")))
|
||||
m.Option("repos", kit.Select(m.Conf(REPOS, "meta.owner")+"/"+m.Option("name"), m.Option("repos")))
|
||||
|
||||
if _, e := os.Stat(path.Join(m.Option("path"), ".git")); e != nil && os.IsNotExist(e) {
|
||||
// 下载仓库
|
||||
if _, e := os.Stat(m.Option("path")); e == nil {
|
||||
m.Option(cli.CMD_DIR, m.Option("path"))
|
||||
m.Cmd(cli.SYSTEM, GIT, "init")
|
||||
m.Cmd(cli.SYSTEM, GIT, "remote", "add", "origin", m.Option("remote"))
|
||||
m.Cmd(cli.SYSTEM, GIT, "remote", "add", "origin", m.Option("repos"))
|
||||
m.Cmd(cli.SYSTEM, GIT, "pull", "origin", "master")
|
||||
} else {
|
||||
m.Cmd(cli.SYSTEM, GIT, "clone", "-b", kit.Select("master", m.Option("branch")),
|
||||
m.Option("remote"), m.Option("path"))
|
||||
m.Option("repos"), m.Option("path"))
|
||||
|
||||
}
|
||||
_repos_insert(m, m.Option("name"), m.Option("path"))
|
||||
|
@ -150,7 +150,7 @@ var Index = &ice.Context{Name: "lark", Help: "机器人",
|
||||
|
||||
kit.Fetch(kit.Value(data, "data.user_list"), func(index int, value map[string]interface{}) {
|
||||
msg := m.Cmd(m.Prefix(USER), value[OPEN_ID])
|
||||
m.Push("avatar", m.Cmdx(mdb.RENDER, web.RENDER.IMG, msg.Append("avatar_72")))
|
||||
// m.Push("avatar", m.Cmdx(mdb.RENDER, web.RENDER.IMG, msg.Append("avatar_72")))
|
||||
m.Push("gender", kit.Select("男", "女", msg.Append("gender") == "2"))
|
||||
m.Push(kit.MDB_NAME, msg.Append(kit.MDB_NAME))
|
||||
m.Push("description", msg.Append("description"))
|
||||
@ -207,7 +207,7 @@ var Index = &ice.Context{Name: "lark", Help: "机器人",
|
||||
|
||||
kit.Fetch(kit.Value(data, "data.members"), func(index int, value map[string]interface{}) {
|
||||
msg := m.Cmd(m.Prefix(USER), value[OPEN_ID])
|
||||
m.Push("avatar", m.Cmdx(mdb.RENDER, web.RENDER.IMG, msg.Append("avatar_72")))
|
||||
// m.Push("avatar", m.Cmdx(mdb.RENDER, web.RENDER.IMG, msg.Append("avatar_72")))
|
||||
m.Push("gender", kit.Select("男", "女", msg.Append("gender") == "2"))
|
||||
m.Push(kit.MDB_NAME, msg.Append(kit.MDB_NAME))
|
||||
m.Push("description", msg.Append("description"))
|
||||
@ -223,7 +223,7 @@ var Index = &ice.Context{Name: "lark", Help: "机器人",
|
||||
data := raw(m, "/open-apis/chat/v4/list")
|
||||
kit.Fetch(kit.Value(data, "data.groups"), func(index int, value map[string]interface{}) {
|
||||
m.Push(CHAT_ID, value[CHAT_ID])
|
||||
m.Push("avatar", m.Cmdx(mdb.RENDER, web.RENDER.IMG, value["avatar"]))
|
||||
// m.Push("avatar", m.Cmdx(mdb.RENDER, web.RENDER.IMG, value["avatar"]))
|
||||
m.Push(kit.MDB_NAME, value[kit.MDB_NAME])
|
||||
m.Push("description", value["description"])
|
||||
m.Push(OPEN_ID, value["owner_open_id"])
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/aaa"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
"github.com/shylinux/icebergs/base/tcp"
|
||||
"github.com/shylinux/icebergs/base/web"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
@ -59,7 +60,7 @@ func init() {
|
||||
m.Option(mdb.FIELDS, m.Conf(m.Prefix(SESS), kit.META_FIELD))
|
||||
if strings.TrimSpace(m.Option(SID)) == "" {
|
||||
m.Option(SID, m.Cmdx(mdb.INSERT, m.Prefix(SESS), "", mdb.HASH, kit.MDB_STATUS, "login",
|
||||
aaa.USERNAME, m.Option(aaa.USERNAME), aaa.HOSTNAME, m.Option(aaa.HOSTNAME), PID, m.Option(PID), PWD, m.Option(PWD)))
|
||||
aaa.USERNAME, m.Option(aaa.USERNAME), tcp.HOSTNAME, m.Option(tcp.HOSTNAME), PID, m.Option(PID), PWD, m.Option(PWD)))
|
||||
} else {
|
||||
m.Cmdy(mdb.MODIFY, m.Prefix(SESS), "", mdb.HASH, kit.MDB_HASH, m.Option(SID), kit.MDB_STATUS, "login")
|
||||
}
|
||||
@ -79,7 +80,7 @@ func init() {
|
||||
msg := m.Cmd(mdb.SELECT, m.Prefix(SESS), "", mdb.HASH, kit.MDB_HASH, strings.TrimSpace(m.Option(SID)))
|
||||
if m.Option(SID, msg.Append(kit.MDB_HASH)) != "" {
|
||||
m.Option(aaa.USERNAME, msg.Append(aaa.USERNAME))
|
||||
m.Option(aaa.HOSTNAME, msg.Append(aaa.HOSTNAME))
|
||||
m.Option(tcp.HOSTNAME, msg.Append(tcp.HOSTNAME))
|
||||
}
|
||||
}
|
||||
m.Render(ice.RENDER_RESULT)
|
||||
|
@ -13,14 +13,14 @@ func init() {
|
||||
"/download": {Name: "/download", Help: "下载", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 || arg[0] == "" {
|
||||
// 文件列表
|
||||
m.Cmdy(web.PROXY, m.Option("you"), web.STORY).Table()
|
||||
m.Cmdy(web.SPACE, m.Option("you"), web.STORY).Table()
|
||||
return
|
||||
}
|
||||
|
||||
// 查找文件
|
||||
if m.Cmdy(web.STORY, "index", arg[0]).Append("text") == "" && m.Option("you") != "" {
|
||||
// 上发文件
|
||||
m.Cmd(web.PROXY, m.Option("you"), web.STORY, "push", arg[0], "dev", arg[0])
|
||||
m.Cmd(web.SPACE, m.Option("you"), web.STORY, "push", arg[0], "dev", arg[0])
|
||||
m.Cmdy(web.STORY, "index", arg[0])
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/aaa"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
"github.com/shylinux/icebergs/base/tcp"
|
||||
"github.com/shylinux/icebergs/base/web"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
@ -44,7 +45,7 @@ func init() {
|
||||
m.Option(mdb.FIELDS, m.Conf(m.Prefix(SESS), kit.META_FIELD))
|
||||
if strings.TrimSpace(m.Option(SID)) == "" {
|
||||
m.Option(SID, m.Cmdx(mdb.INSERT, m.Prefix(SESS), "", mdb.HASH, kit.MDB_STATUS, "login",
|
||||
aaa.USERNAME, m.Option(aaa.USERNAME), aaa.HOSTNAME, m.Option(aaa.HOSTNAME), PID, m.Option(PID), PWD, m.Option(PWD)))
|
||||
aaa.USERNAME, m.Option(aaa.USERNAME), tcp.HOSTNAME, m.Option(tcp.HOSTNAME), PID, m.Option(PID), PWD, m.Option(PWD)))
|
||||
} else {
|
||||
m.Cmdy(mdb.MODIFY, m.Prefix(SESS), "", mdb.HASH, kit.MDB_HASH, m.Option(SID), kit.MDB_STATUS, "login")
|
||||
}
|
||||
@ -64,7 +65,7 @@ func init() {
|
||||
msg := m.Cmd(mdb.SELECT, m.Prefix(SESS), "", mdb.HASH, kit.MDB_HASH, strings.TrimSpace(m.Option(SID)))
|
||||
if m.Option(SID, msg.Append(kit.MDB_HASH)) != "" {
|
||||
m.Option(aaa.USERNAME, msg.Append(aaa.USERNAME))
|
||||
m.Option(aaa.HOSTNAME, msg.Append(aaa.HOSTNAME))
|
||||
m.Option(tcp.HOSTNAME, msg.Append(tcp.HOSTNAME))
|
||||
}
|
||||
}
|
||||
m.Render(ice.RENDER_RESULT)
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/aaa"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
"github.com/shylinux/icebergs/base/tcp"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"strings"
|
||||
@ -57,7 +58,7 @@ func init() {
|
||||
ls := strings.SplitN(strings.TrimSpace(m.Option(ARG)), " ", 4)
|
||||
if text := strings.TrimSpace(strings.Join(ls[3:], " ")); text != "" {
|
||||
m.Cmd(mdb.INSERT, m.Prefix(SYNC), "", mdb.LIST, kit.MDB_TYPE, SHELL, kit.MDB_NAME, ls[0],
|
||||
aaa.HOSTNAME, m.Option(aaa.HOSTNAME), aaa.USERNAME, m.Option(aaa.USERNAME),
|
||||
tcp.HOSTNAME, m.Option(tcp.HOSTNAME), aaa.USERNAME, m.Option(aaa.USERNAME),
|
||||
kit.MDB_TEXT, text, PWD, m.Option(PWD), kit.MDB_TIME, ls[1]+" "+ls[2])
|
||||
|
||||
}
|
||||
|
6
type.go
6
type.go
@ -303,7 +303,7 @@ func (c *Context) Start(m *Message, arg ...string) bool {
|
||||
if wait <- true; c.server != nil {
|
||||
c.server.Start(m, arg...)
|
||||
}
|
||||
if m.Done(); m.wait != nil {
|
||||
if m.Done(true); m.wait != nil {
|
||||
m.wait <- true
|
||||
}
|
||||
}, p)
|
||||
@ -565,6 +565,8 @@ func (m *Message) Search(key interface{}, cb interface{}) *Message {
|
||||
p := m.target.root
|
||||
if ctx, ok := names[key].(*Context); ok {
|
||||
p = ctx
|
||||
} else if key == "ice." {
|
||||
p, key = m.target.root, ""
|
||||
} else if key == "." {
|
||||
p, key = m.target, ""
|
||||
} else if key == ".." {
|
||||
@ -625,7 +627,7 @@ func (m *Message) Search(key interface{}, cb interface{}) *Message {
|
||||
}
|
||||
}
|
||||
case func(p *Context, s *Context, key string, conf *Config):
|
||||
for _, p := range []*Context{p, m.target, m.source} {
|
||||
for _, p := range []*Context{m.target, p, m.source} {
|
||||
for s := p; s != nil; s = s.context {
|
||||
if cmd, ok := s.Configs[key]; ok {
|
||||
cb(s.context, s, key, cmd)
|
||||
|
Loading…
x
Reference in New Issue
Block a user