1
0
forked from x/icebergs
This commit is contained in:
shaoying 2022-11-20 12:07:54 +08:00
parent be05bc9a5f
commit 028a6ba82b
15 changed files with 123 additions and 208 deletions

View File

@ -2,8 +2,6 @@ package aaa
import (
ice "shylinux.com/x/icebergs"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs"
)
const (
@ -14,8 +12,3 @@ const AAA = "aaa"
var Index = &ice.Context{Name: AAA, Help: "认证模块"}
func init() { ice.Index.Register(Index, nil, ROLE, SESS, TOTP, USER, RSA) }
func Right(m *ice.Message, arg ...ice.Any) bool {
return m.Option(ice.MSG_USERROLE) == ROOT || !m.Warn(m.Cmdx(ROLE, RIGHT, m.Option(ice.MSG_USERROLE), arg) != ice.OK,
ice.ErrNotRight, kit.Join(kit.Simple(arg), ice.PT), USERROLE, m.Option(ice.MSG_USERROLE), logs.FileLineMeta(logs.FileLine(2)))
}

View File

@ -1,6 +0,0 @@
chapter "aaa"
field "角色" role
field "会话" sess
field "令牌" totp
field "用户" user

View File

@ -7,6 +7,7 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs"
)
func _role_chain(arg ...string) string {
@ -14,15 +15,15 @@ func _role_chain(arg ...string) string {
return strings.TrimPrefix(strings.TrimSuffix(strings.ReplaceAll(key, ice.PS, ice.PT), ice.PT), ice.PT)
}
func _role_black(m *ice.Message, userrole, chain string) {
mdb.HashSelectUpdate(m, userrole, func(value ice.Map) {
m.Logs(mdb.INSERT, ROLE, userrole, BLACK, chain)
mdb.HashSelectUpdate(m, userrole, func(value ice.Map) {
black := value[BLACK].(ice.Map)
black[chain] = true
})
}
func _role_white(m *ice.Message, userrole, chain string) {
mdb.HashSelectUpdate(m, userrole, func(value ice.Map) {
m.Logs(mdb.INSERT, ROLE, userrole, WHITE, chain)
mdb.HashSelectUpdate(m, userrole, func(value ice.Map) {
white := value[WHITE].(ice.Map)
white[chain] = true
})
@ -45,11 +46,7 @@ func _role_right(m *ice.Message, userrole string, keys ...string) (ok bool) {
return true
}
mdb.HashSelectDetail(m, kit.Select(VOID, userrole), func(value ice.Map) {
if userrole == TECH {
ok = _role_check(value, keys, true)
} else {
ok = _role_check(value, keys, false)
}
ok = _role_check(value, keys, userrole == TECH)
})
return ok
}
@ -84,27 +81,24 @@ const ROLE = "role"
func init() {
Index.MergeCommands(ice.Commands{
ROLE: {Name: "role role auto insert", Help: "角色", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
mdb.Rich(m, ROLE, nil, kit.Dict(mdb.NAME, TECH, BLACK, kit.Dict(), WHITE, kit.Dict()))
mdb.Rich(m, ROLE, nil, kit.Dict(mdb.NAME, VOID, WHITE, kit.Dict(), BLACK, kit.Dict()))
m.Cmd(ROLE, WHITE, VOID, ice.SRC)
m.Cmd(ROLE, WHITE, VOID, ice.BIN)
m.Cmd(ROLE, WHITE, VOID, ice.USR)
m.Cmd(ROLE, BLACK, VOID, ice.USR_LOCAL)
m.Cmd(ROLE, WHITE, VOID, ice.USR_LOCAL_GO)
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Cmd("", mdb.CREATE, TECH, VOID) }},
mdb.CREATE: {Hand: func(m *ice.Message, arg ...string) {
for _, role := range arg {
mdb.Rich(m, ROLE, nil, kit.Dict(mdb.NAME, role, BLACK, kit.Dict(), WHITE, kit.Dict()))
}
}},
mdb.INSERT: {Name: "insert role=void,tech zone=white,black key=", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
mdb.HashSelectUpdate(m, m.Option(ROLE), func(key string, value ice.Map) {
mdb.INSERT: {Name: "insert role=void,tech zone=white,black key", Hand: func(m *ice.Message, arg ...string) {
m.Logs(mdb.INSERT, ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY))
mdb.HashSelectUpdate(m, m.Option(ROLE), func(key string, value ice.Map) {
list := value[m.Option(mdb.ZONE)].(ice.Map)
list[_role_chain(m.Option(mdb.KEY))] = true
})
}},
mdb.DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
mdb.HashSelectUpdate(m, m.Option(ROLE), func(key string, value ice.Map) {
mdb.DELETE: {Hand: func(m *ice.Message, arg ...string) {
m.Logs(mdb.DELETE, ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY))
mdb.HashSelectUpdate(m, m.Option(ROLE), func(key string, value ice.Map) {
list := value[m.Option(mdb.ZONE)].(ice.Map)
delete(list, _role_chain(m.Option(mdb.KEY)))
list[_role_chain(m.Option(mdb.KEY))] = false
})
}},
BLACK: {Name: "black role chain", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) {
@ -113,7 +107,7 @@ func init() {
WHITE: {Name: "white role chain", Help: "白名单", Hand: func(m *ice.Message, arg ...string) {
_role_white(m, arg[0], _role_chain(arg[1:]...))
}},
RIGHT: {Name: "right role chain", Help: "权限", Hand: func(m *ice.Message, arg ...string) {
RIGHT: {Name: "right role chain", Help: "查权限", Hand: func(m *ice.Message, arg ...string) {
if _role_right(m, arg[0], kit.Split(_role_chain(arg[1:]...), ice.PT)...) {
m.Echo(ice.OK)
}
@ -124,6 +118,10 @@ func init() {
})
}
func Right(m *ice.Message, arg ...ice.Any) bool {
return m.Option(ice.MSG_USERROLE) == ROOT || !m.Warn(m.Cmdx(ROLE, RIGHT, m.Option(ice.MSG_USERROLE), arg) != ice.OK,
ice.ErrNotRight, kit.Join(kit.Simple(arg), ice.PT), USERROLE, m.Option(ice.MSG_USERROLE), logs.FileLineMeta(logs.FileLine(2)))
}
func RoleRight(m *ice.Message, userrole string, arg ...string) bool {
return m.Cmdx(ROLE, RIGHT, userrole, arg) == ice.OK
}
@ -131,18 +129,18 @@ func RoleAction(cmds ...string) ice.Actions {
return ice.Actions{ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(ROLE, WHITE, VOID, m.CommandKey())
m.Cmd(ROLE, WHITE, VOID, m.PrefixKey())
m.Cmd(ROLE, BLACK, VOID, m.PrefixKey(), "action")
m.Cmd(ROLE, BLACK, VOID, m.PrefixKey(), ice.ACTION)
for _, cmd := range cmds {
m.Cmd(ROLE, WHITE, VOID, m.PrefixKey(), "action", cmd)
m.Cmd(ROLE, WHITE, VOID, m.PrefixKey(), ice.ACTION, cmd)
}
}}}
}
func WhiteAction(cmds ...string) ice.Actions {
return ice.Actions{ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(ROLE, WHITE, VOID, m.CommandKey())
m.Cmd(ROLE, BLACK, VOID, m.CommandKey(), "action")
m.Cmd(ROLE, BLACK, VOID, m.CommandKey(), ice.ACTION)
for _, cmd := range cmds {
m.Cmd(ROLE, WHITE, VOID, m.CommandKey(), "action", cmd)
m.Cmd(ROLE, WHITE, VOID, m.CommandKey(), ice.ACTION, cmd)
}
}}}
}
@ -150,7 +148,7 @@ func BlackAction(cmds ...string) ice.Actions {
return ice.Actions{ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(ROLE, WHITE, VOID, m.CommandKey())
for _, cmd := range cmds {
m.Cmd(ROLE, BLACK, VOID, m.CommandKey(), "action", cmd)
m.Cmd(ROLE, BLACK, VOID, m.CommandKey(), ice.ACTION, cmd)
}
}}}
}

View File

@ -9,30 +9,15 @@ import (
)
func _sess_check(m *ice.Message, sessid string) {
m.Option(ice.MSG_USERROLE, VOID)
m.Option(ice.MSG_USERNAME, "")
m.Option(ice.MSG_USERNICK, "")
if sessid == "" {
return
}
_source := logs.FileLineMeta(logs.FileLine(-1))
m.Assert(sessid != "")
mdb.HashSelectDetail(m, sessid, func(value ice.Map) {
if m.Warn(kit.Time(kit.Format(value[mdb.TIME])) < kit.Time(m.Time()), ice.ErrNotValid, sessid) {
return // 会话超时
if !m.WarnTimeNotValid(value[mdb.TIME], sessid) {
SessAuth(m, value)
}
m.Auth(
USERROLE, m.Option(ice.MSG_USERROLE, value[USERROLE]),
USERNAME, m.Option(ice.MSG_USERNAME, value[USERNAME]),
USERNICK, m.Option(ice.MSG_USERNICK, value[USERNICK]),
_source,
)
})
}
func _sess_create(m *ice.Message, username string) (h string) {
if m.Warn(username == "", ice.ErrNotValid, username) {
return
}
m.Assert(username != "")
if msg := m.Cmd(USER, username); msg.Length() > 0 {
h = mdb.HashCreate(m, msg.AppendSimple(USERROLE, USERNAME, USERNICK), IP, m.Option(ice.MSG_USERIP), UA, m.Option(ice.MSG_USERUA))
} else {
@ -61,18 +46,10 @@ const SESS = "sess"
func init() {
Index.MergeCommands(ice.Commands{
SESS: {Name: "sess hash auto prunes", Help: "会话", Actions: ice.MergeActions(ice.Actions{
mdb.CREATE: {Name: "create username", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
mdb.CREATE: {Name: "create username", Hand: func(m *ice.Message, arg ...string) {
_sess_create(m, m.Option(USERNAME))
}},
SESS_CREATE: {Name: "sess.create", Help: "事件", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(mdb.EXPORT, m.Prefix(SESS), "", mdb.HASH)
m.Cmd(mdb.IMPORT, m.Prefix(SESS), "", mdb.HASH)
}},
USER_CREATE: {Name: "user.create", Help: "检查", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(mdb.EXPORT, m.Prefix(USER), "", mdb.HASH)
m.Cmd(mdb.IMPORT, m.Prefix(USER), "", mdb.HASH)
}},
CHECK: {Name: "check sessid", Help: "检查", Hand: func(m *ice.Message, arg ...string) {
CHECK: {Name: "check sessid", Hand: func(m *ice.Message, arg ...string) {
_sess_check(m, m.Option(SESSID))
}},
}, mdb.HashAction(mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,userrole,username,usernick,ip,ua", mdb.EXPIRE, "720h"))},
@ -80,6 +57,9 @@ func init() {
}
func SessCreate(m *ice.Message, username string) string {
if m.Warn(username == "", ice.ErrNotValid, username) {
return ""
}
return m.Option(ice.MSG_SESSID, m.Cmdx(SESS, mdb.CREATE, username))
}
func SessCheck(m *ice.Message, sessid string) bool {
@ -88,15 +68,17 @@ func SessCheck(m *ice.Message, sessid string) bool {
m.Option(ice.MSG_USERNICK, "")
return sessid != "" && m.Cmdy(SESS, CHECK, sessid).Option(ice.MSG_USERNAME) != ""
}
func UserLogout(m *ice.Message, arg ...string) {
func SessAuth(m *ice.Message, value ice.Map, arg ...string) {
m.Auth(
USERROLE, m.Option(ice.MSG_USERROLE, value[USERROLE]),
USERNAME, m.Option(ice.MSG_USERNAME, value[USERNAME]),
USERNICK, m.Option(ice.MSG_USERNICK, value[USERNICK]),
arg, logs.FileLineMeta(logs.FileLine(-1)),
)
}
func SessLogout(m *ice.Message, arg ...string) {
if m.Option(ice.MSG_SESSID) == "" {
return
}
m.Cmd(SESS, mdb.REMOVE, kit.Dict(mdb.HASH, m.Option(ice.MSG_SESSID)))
}
func SessAuth(m *ice.Message, value ice.Maps, arg ...string) {
m.Option(ice.MSG_USERROLE, value[USERROLE])
m.Option(ice.MSG_USERNAME, value[USERNAME])
m.Option(ice.MSG_USERNICK, value[USERNICK])
m.Auth(USERROLE, value[USERROLE], USERNAME, value[USERNAME], USERNICK, value[USERNICK], arg, logs.FileLineMeta(logs.FileLine(2)))
}

View File

@ -23,40 +23,37 @@ func _totp_gen(per int64) string {
}
func _totp_get(key string, num int, per int64) string {
now := kit.Int64(time.Now().Unix() / per)
buf := []byte{}
for i := 0; i < 8; i++ {
buf = append(buf, byte((uint64(now) >> uint64(((7 - i) * 8)))))
}
if l := len(key) % 8; l != 0 {
key += strings.Repeat("=", 8-l)
}
s, _ := base32.StdEncoding.DecodeString(strings.ToUpper(key))
hm := hmac.New(sha1.New, s)
hm.Write(buf)
b := hm.Sum(nil)
n := b[len(b)-1] & 0x0F
res := int64(b[n]&0x7F)<<24 | int64(b[n+1]&0xFF)<<16 | int64(b[n+2]&0xFF)<<8 | int64(b[n+3]&0xFF)
return kit.Format(kit.Format("%%0%dd", num), res%int64(math.Pow10(num)))
}
const (
SECRET = "secret"
PERIOD = "period"
NUMBER = "number"
TOKEN = "token"
)
const TOTP = "totp"
func init() {
const (
SECRET = "secret"
PERIOD = "period"
NUMBER = "number"
)
Index.MergeCommands(ice.Commands{
TOTP: {Name: "totp name auto create", Help: "令牌", Actions: ice.MergeActions(ice.Actions{
mdb.CREATE: {Name: "create name=hi secret period=30 number=6", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
if m.Option(SECRET) == "" { // 创建密钥
mdb.CREATE: {Name: "create name=hi secret period=30 number=6", Hand: func(m *ice.Message, arg ...string) {
if m.Option(SECRET) == "" {
m.Option(SECRET, _totp_gen(kit.Int64(m.Option(PERIOD))))
}
mdb.HashCreate(m, m.OptionSimple(mdb.NAME, SECRET, PERIOD, NUMBER))
@ -68,11 +65,9 @@ func init() {
}
m.Push(mdb.TIME, m.Time())
m.Push(mdb.NAME, value[mdb.NAME])
period := kit.Int64(value[PERIOD])
m.Push("rest", period-time.Now().Unix()%period)
m.Push("code", _totp_get(value[SECRET], kit.Int(value[NUMBER]), period))
if len(arg) > 0 {
m.PushQRCode(mdb.SCAN, kit.Format(m.Config(mdb.LINK), value[mdb.NAME], value[SECRET]))
m.Echo(_totp_get(value[SECRET], kit.Int(value[NUMBER]), kit.Int64(value[PERIOD])))

View File

@ -5,7 +5,6 @@ import (
"shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs"
)
func _user_create(m *ice.Message, name, word string, arg ...string) {
@ -25,21 +24,10 @@ func _user_login(m *ice.Message, name, word string) {
if m.Warn(name == "", ice.ErrNotValid, name) {
return
}
if !mdb.HashSelectDetail(m.Spawn(), name, nil) {
_user_create(m.Spawn(), name, word)
}
_source := logs.FileLineMeta(logs.FileLine(-1))
mdb.HashSelectDetail(m.Spawn(), name, func(value ice.Map) {
if m.Warn(word != "" && word != kit.Format(kit.Value(value, PASSWORD)), ice.ErrNotRight) {
return
if !m.Warn(word != "" && word != kit.Format(value[PASSWORD]), ice.ErrNotValid) {
SessAuth(m, value)
}
m.Auth(
USERROLE, m.Option(ice.MSG_USERROLE, value[USERROLE]),
USERNAME, m.Option(ice.MSG_USERNAME, value[USERNAME]),
USERNICK, m.Option(ice.MSG_USERNICK, value[USERNICK]),
_source,
)
})
}
@ -53,15 +41,15 @@ const (
CITY = "city"
COUNTRY = "country"
LANGUAGE = "language"
PROVINCE = "province"
LANGUAGE = "language"
)
const (
USERROLE = "userrole"
USERNAME = "username"
PASSWORD = "password"
USERNICK = "usernick"
USERZONE = "userzone"
USERROLE = "userrole"
USER_CREATE = "user.create"
@ -72,34 +60,28 @@ const USER = "user"
func init() {
Index.MergeCommands(ice.Commands{
USER: {Name: "user username auto create", Help: "用户", Actions: ice.MergeActions(ice.Actions{
mdb.CREATE: {Name: "create username password userrole=void,tech usernick", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
_user_create(m, m.Option(USERNAME), m.Option(PASSWORD), m.OptionSimple(USERROLE, USERNICK)...)
mdb.CREATE: {Name: "create username* password usernick userzone userrole=void,tech", Hand: func(m *ice.Message, arg ...string) {
_user_create(m, m.Option(USERNAME), m.Option(PASSWORD), m.OptionSimple(USERNICK, USERZONE, USERROLE)...)
}},
LOGIN: {Name: "login username password", Help: "登录", Hand: func(m *ice.Message, arg ...string) {
LOGIN: {Name: "login username* password", Hand: func(m *ice.Message, arg ...string) {
_user_login(m, m.Option(USERNAME), m.Option(PASSWORD))
}},
}, mdb.HashSearchAction(mdb.SHORT, USERNAME, mdb.FIELD, "time,userrole,username,usernick,userzone"))},
}, mdb.HashSearchAction(mdb.SHORT, USERNAME, mdb.FIELD, "time,username,usernick,userzone,userrole"))},
})
}
func UserRoot(m *ice.Message, arg ...string) *ice.Message { // password username userrole
userrole := m.Option(ice.MSG_USERROLE, ROOT)
username := m.Option(ice.MSG_USERNAME, kit.Select(ice.Info.UserName, arg, 1))
usernick := m.Option(ice.MSG_USERNICK, kit.Select(UserNick(m, username), arg, 2))
if len(arg) > 0 {
m.Cmd(USER, mdb.CREATE, username, kit.Select("", arg, 0), userrole, usernick)
ice.Info.UserName = username
}
return m
}
func UserInfo(m *ice.Message, name ice.Any, key, meta string) (value string) {
if m.Cmd(USER, name, func(val ice.Maps) {
value = val[key]
}).Length() == 0 && kit.Format(name) == m.Option(ice.MSG_USERNAME) {
if m.Cmd(USER, name, func(val ice.Maps) { value = val[key] }).Length() == 0 && kit.Format(name) == m.Option(ice.MSG_USERNAME) {
return m.Option(meta)
}
return
}
func UserNick(m *ice.Message, username ice.Any) (nick string) {
return UserInfo(m, username, USERNICK, ice.MSG_USERNICK)
}
func UserZone(m *ice.Message, username ice.Any) (zone string) {
return UserInfo(m, username, USERZONE, ice.MSG_USERZONE)
}
func UserRole(m *ice.Message, username ice.Any) (role string) {
if username == "" {
return VOID
@ -109,15 +91,19 @@ func UserRole(m *ice.Message, username ice.Any) (role string) {
}
return UserInfo(m, username, USERROLE, ice.MSG_USERROLE)
}
func UserNick(m *ice.Message, username ice.Any) (nick string) {
return UserInfo(m, username, USERNICK, ice.MSG_USERNICK)
}
func UserZone(m *ice.Message, username ice.Any) (zone string) {
return UserInfo(m, username, USERZONE, ice.MSG_USERZONE)
}
func UserLogin(m *ice.Message, username, password string) bool {
m.Option(ice.MSG_USERROLE, VOID)
m.Option(ice.MSG_USERNAME, "")
m.Option(ice.MSG_USERNICK, "")
return m.Cmdy(USER, LOGIN, username, password).Option(ice.MSG_USERNAME) != ""
}
func UserRoot(m *ice.Message, arg ...string) *ice.Message {
username := m.Option(ice.MSG_USERNAME, kit.Select(ice.Info.UserName, arg, 1))
usernick := m.Option(ice.MSG_USERNICK, kit.Select(UserNick(m, username), arg, 2))
userrole := m.Option(ice.MSG_USERROLE, kit.Select(ROOT, arg, 3))
if len(arg) > 0 {
m.Cmd(USER, mdb.CREATE, username, kit.Select("", arg, 0), usernick, "", userrole)
ice.Info.UserName = username
}
return m
}

View File

@ -1,9 +0,0 @@
chapter "cli"
field "环境" runtime
field "扫码" qrcode
field "命令" system
field "守护" daemon
field "启动" forever
field "镜像" mirrors

View File

@ -15,7 +15,7 @@ import (
func _daemon_exec(m *ice.Message, cmd *exec.Cmd) {
if r, ok := m.Optionv(CMD_INPUT).(io.Reader); ok {
cmd.Stdin = r // 输入流
cmd.Stdin = r
}
if w := _system_out(m, CMD_OUTPUT); w != nil {
cmd.Stdout, cmd.Stderr = w, w
@ -23,21 +23,18 @@ func _daemon_exec(m *ice.Message, cmd *exec.Cmd) {
if w := _system_out(m, CMD_ERRPUT); w != nil {
cmd.Stderr = w
}
h := mdb.HashCreate(m.Spawn(), ice.CMD, kit.Join(cmd.Args, ice.SP),
STATUS, START, DIR, cmd.Dir, ENV, kit.Select("", cmd.Env),
m.OptionSimple(CMD_INPUT, CMD_OUTPUT, CMD_ERRPUT, mdb.CACHE_CLEAR_ON_EXIT),
)
// 启动服务
if e := cmd.Start(); m.Warn(e, ice.ErrNotStart, cmd.Args) {
mdb.HashModify(m, h, STATUS, ERROR, ERROR, e)
return // 启动失败
return
}
mdb.HashSelectUpdate(m, h, func(value ice.Map) { value[PID] = cmd.Process.Pid })
m.Echo("%d", cmd.Process.Pid)
m.Go(func() { // 等待结果
m.Go(func() {
if e := cmd.Wait(); !m.Warn(e, ice.ErrNotStart, cmd.Args) && cmd.ProcessState.ExitCode() == 0 {
m.Cost(CODE, cmd.ProcessState.ExitCode(), ctx.ARGS, cmd.Args)
mdb.HashModify(m, mdb.HASH, h, STATUS, STOP)
@ -48,11 +45,10 @@ func _daemon_exec(m *ice.Message, cmd *exec.Cmd) {
}
})
}
status := mdb.HashSelectField(m, h, STATUS)
switch m.Sleep300ms(); cb := m.OptionCB("").(type) {
case func(string) bool:
if !cb(status) { // 拉起服务
if !cb(status) {
m.Cmdy(DAEMON, cmd.Path, cmd.Args)
}
case func(string):
@ -91,18 +87,18 @@ const (
RELOAD = "reload"
RESTART = "restart"
BEGIN = "begin"
START = "start"
OPEN = "open"
CLOSE = "close"
START = "start"
STOP = "stop"
BEGIN = "begin"
END = "end"
MAIN = "main"
CODE = "code"
COST = "cost"
BACK = "back"
FROM = "from"
MAIN = "main"
)
const DAEMON = "daemon"
@ -113,15 +109,14 @@ func init() {
ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) {
mdb.HashPrunesValue(m, mdb.CACHE_CLEAR_ON_EXIT, ice.TRUE)
}},
START: {Name: "start cmd env dir", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Option(CMD_DIR, m.Option(DIR))
m.Option(CMD_ENV, kit.Split(m.Option(ENV), " ="))
START: {Name: "start cmd dir env", Hand: func(m *ice.Message, arg ...string) {
m.Options(CMD_DIR, m.Option(DIR), CMD_ENV, kit.Split(m.Option(ENV), " ="))
_daemon_exec(m, _system_cmd(m, kit.Split(m.Option(ice.CMD))...))
}},
RESTART: {Name: "restart", Help: "重启", Hand: func(m *ice.Message, arg ...string) {
RESTART: {Hand: func(m *ice.Message, arg ...string) {
m.Cmdy("", STOP).Sleep3s().Cmdy("", START)
}},
STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
STOP: {Hand: func(m *ice.Message, arg ...string) {
m.OptionFields(m.Config(mdb.FIELD))
h, pid := m.Option(mdb.HASH), m.Option(PID)
mdb.HashSelect(m, m.Option(mdb.HASH)).Tables(func(value ice.Maps) {

View File

@ -21,7 +21,7 @@ const FOREVER = "forever"
func init() {
Index.MergeCommands(ice.Commands{
FOREVER: {Name: "forever auto", Help: "启动", Actions: ice.Actions{
START: {Name: "start", Help: "服务", Hand: func(m *ice.Message, arg ...string) {
START: {Hand: func(m *ice.Message, arg ...string) {
env := []string{PATH, BinPath(), HOME, kit.Select(kit.Path(""), os.Getenv(HOME))}
for _, k := range ENV_LIST {
if kit.Env(k) != "" {
@ -29,7 +29,7 @@ func init() {
}
}
for _, v := range os.Environ() {
if ls := kit.Split(v, "=", "="); kit.IndexOf(env, ls[0]) == -1 && len(ls) > 1 {
if ls := kit.Split(v, ice.EQ, ice.EQ); kit.IndexOf(env, ls[0]) == -1 && len(ls) > 1 {
env = append(env, ls[0], ls[1])
}
}
@ -40,40 +40,30 @@ func init() {
if p := kit.Env(CTX_LOG); p != "" {
m.Optionv(CMD_ERRPUT, p)
}
m.Cmd(FOREVER, STOP)
if bin := kit.Select(os.Args[0], ice.BIN_ICE_BIN, nfs.ExistsFile(m, ice.BIN_ICE_BIN)); len(arg) > 0 && arg[0] == "space" {
m.Cmdy(FOREVER, bin, "space", "dial", ice.DEV, ice.OPS, arg[2:])
if bin := kit.Select(os.Args[0], ice.BIN_ICE_BIN, nfs.ExistsFile(m, ice.BIN_ICE_BIN)); len(arg) > 0 && arg[0] == ice.SPACE {
m.Cmdy(FOREVER, bin, ice.SPACE, "dial", ice.DEV, ice.OPS, arg[2:])
} else {
m.Cmdy(FOREVER, bin, "serve", START, ice.DEV, "", aaa.USERNAME, aaa.ROOT, aaa.PASSWORD, aaa.ROOT, arg)
m.Cmdy(FOREVER, bin, ice.SERVE, START, ice.DEV, "", aaa.USERNAME, aaa.ROOT, aaa.PASSWORD, aaa.ROOT, arg)
}
}},
RESTART: {Name: "restart", Help: "重启", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(gdb.SIGNAL, gdb.RESTART)
}},
STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(gdb.SIGNAL, gdb.STOP)
}},
RESTART: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(gdb.SIGNAL, gdb.RESTART) }},
STOP: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(gdb.SIGNAL, gdb.STOP) }},
}, Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 {
m.Cmdy(RUNTIME, BOOTINFO)
return
}
for {
if logs.Println("run %s", kit.Join(arg, ice.SP)); IsSuccess(m.Cmd(SYSTEM, arg)) {
logs.Println(ice.EXIT) // 正常退出
if logs.Println("run %s", kit.Join(arg, ice.SP)); IsSuccess(m.Sleep("1s", SYSTEM, arg)) {
logs.Println(ice.EXIT)
break
}
if logs.Println(); m.Config("log.save") == ice.TRUE {
back := kit.Format("var/log.%s", logs.Now().Format("20060102_150405"))
m.Cmd(SYSTEM, "cp", "-r", "var/log", back, ice.Maps{CMD_OUTPUT: ""})
m.Cmd(SYSTEM, "cp", "bin/boot.log", path.Join(back, "boot.log"), ice.Maps{CMD_OUTPUT: ""})
// if IsSuccess(m.Cmd(SYSTEM, "grep", "fatal error: concurrent map read and map write", "bin/boot.log", ice.Maps{CMD_OUTPUT: ""})) {
// m.Cmd(SYSTEM, "cp", "bin/boot.log", path.Join(back, "boot.log"), ice.Maps{CMD_OUTPUT: ""})
// }
}
m.Sleep("1s")
}
}},
})

View File

@ -26,7 +26,7 @@ func init() {
Index.MergeCommands(ice.Commands{
MIRRORS: {Name: "mirrors cli auto", Help: "软件镜像", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
m.Conf(m.Prefix(MIRRORS), kit.Keys(mdb.HASH), "")
m.Conf(m.PrefixKey(), kit.Keys(mdb.HASH), "")
IsAlpine(m, "curl")
IsAlpine(m, "make")
IsAlpine(m, "gcc")
@ -36,7 +36,8 @@ func init() {
mdb.ZoneInsert(m, CLI, "go", CMD, kit.Format("install download https://golang.google.cn/dl/go1.15.5.%s-%s.tar.gz usr/local", runtime.GOOS, runtime.GOARCH))
}
}},
mdb.INSERT: {Name: "insert cli osid cmd", Help: "添加"},
mdb.INSERT: {Name: "insert cli osid cmd"},
ALPINE: {Name: "alpine cli cmd", Hand: func(m *ice.Message, arg ...string) { IsAlpine(m, arg...) }},
CMD: {Name: "cmd cli osid", Help: "安装", Hand: func(m *ice.Message, arg ...string) {
osid := kit.Select(m.Conf(RUNTIME, kit.Keys(HOST, OSID)), m.Option(OSID))
mdb.ZoneSelectCB(m, m.Option(CLI), func(value ice.Map) {
@ -45,9 +46,6 @@ func init() {
}
})
}},
ALPINE: {Name: "alpine cli cmd", Help: "安装", Hand: func(m *ice.Message, arg ...string) {
IsAlpine(m, arg...)
}},
}, mdb.ZoneAction(mdb.SHORT, CLI, mdb.FIELD, "time,id,osid,cmd"))},
})
}
@ -56,46 +54,27 @@ func osid(m *ice.Message, sys string) bool {
osid := runtime.GOOS
m.Option(ice.MSG_USERROLE, aaa.ROOT)
m.Cmd(nfs.CAT, "/etc/os-release", func(text string) {
if ls := kit.Split(text, "="); len(ls) > 1 {
if ls := kit.Split(text, ice.EQ); len(ls) > 1 {
switch ls[0] {
case "ID", "ID_LIKE":
osid = strings.TrimSpace(ls[1] + ice.SP + osid)
}
}
})
if strings.Contains(osid, sys) {
return true
}
return false
}
func IsAlpine(m *ice.Message, arg ...string) bool {
if osid(m, ALPINE) {
func insert(m *ice.Message, cmd string, arg ...string) bool {
if len(arg) > 0 {
m.Go(func() {
m.Sleep300ms()
m.Cmd(mdb.INSERT, kit.Keys(CLI, MIRRORS), "", mdb.ZONE, arg[0], OSID, ALPINE, CMD, "system apk add "+kit.Select(arg[0], arg, 1))
m.Cmd(mdb.INSERT, kit.Keys(CLI, MIRRORS), "", mdb.ZONE, arg[0], OSID, ALPINE, CMD, cmd+ice.SP+kit.Select(arg[0], arg, 1))
})
}
return true
}
return false
}
func IsCentos(m *ice.Message, arg ...string) bool {
if osid(m, ALPINE) {
if len(arg) > 0 {
m.Cmd(mdb.INSERT, kit.Keys(CLI, MIRRORS), "", mdb.ZONE, arg[0], OSID, CENTOS, CMD, "yum install -y "+kit.Select(arg[0], arg, 1))
}
return true
}
return false
}
func IsUbuntu(m *ice.Message, arg ...string) bool {
if osid(m, ALPINE) {
if len(arg) > 0 {
m.Cmd(mdb.INSERT, kit.Keys(CLI, MIRRORS), "", mdb.ZONE, arg[0], OSID, UBUNTU, CMD, "yum install -y "+kit.Select(arg[0], arg, 1))
}
return true
}
return false
}
func IsAlpine(m *ice.Message, arg ...string) bool { return osid(m, ALPINE) && insert(m, "system apk add", arg...) }
func IsCentos(m *ice.Message, arg ...string) bool { return osid(m, CENTOS) && insert(m, "yum install -y", arg...) }
func IsUbuntu(m *ice.Message, arg ...string) bool { return osid(m, UBUNTU) && insert(m, "apt get -y", arg...) }

View File

@ -173,6 +173,13 @@ const DIR = "dir"
func init() {
Index.MergeCommands(ice.Commands{
DIR: {Name: "dir path field auto upload", Help: "目录", Actions: ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, ice.SRC)
m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, ice.BIN)
m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, ice.USR)
m.Cmd(aaa.ROLE, aaa.BLACK, aaa.VOID, ice.USR_LOCAL)
m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, ice.USR_LOCAL_GO)
}},
mdb.UPLOAD: {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy("web.cache", "upload_watch", m.Option(PATH))
}},

View File

@ -32,7 +32,7 @@ func _action_auth(m *ice.Message, share string) *ice.Message {
return msg
}
m.Tables(func(value ice.Maps) {
aaa.SessAuth(m, value, RIVER, m.Option(ice.MSG_RIVER, msg.Append(RIVER)), STORM, m.Option(ice.MSG_STORM, msg.Append(STORM)))
aaa.SessAuth(m, kit.Dict(value), RIVER, m.Option(ice.MSG_RIVER, msg.Append(RIVER)), STORM, m.Option(ice.MSG_STORM, msg.Append(STORM)))
})
if m.Warn(!_river_right(m, msg.Append(web.RIVER)), ice.ErrNotRight) {
msg.Append(mdb.TYPE, "")

View File

@ -10,6 +10,7 @@ import (
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/tcp"
"shylinux.com/x/icebergs/base/web"
kit "shylinux.com/x/toolkits"
)
func _header_users(m *ice.Message, arg ...string) {
@ -46,7 +47,7 @@ func _header_check(m *ice.Message, arg ...string) bool {
}
switch value[mdb.TYPE] {
case web.STORM, web.FIELD:
aaa.SessAuth(m, value)
aaa.SessAuth(m, kit.Dict(value))
}
})
}
@ -75,7 +76,7 @@ func init() {
web.RenderCookie(m, aaa.SessCreate(m, arg[0]))
}
}},
aaa.LOGOUT: {Hand: aaa.UserLogout},
aaa.LOGOUT: {Hand: aaa.SessLogout},
aaa.PASSWORD: {Hand: _header_users},
aaa.USERNICK: {Hand: _header_users},
aaa.LANGUAGE: {Hand: _header_users},

View File

@ -87,6 +87,9 @@ func (m *Message) Cost(arg ...Any) *Message {
func (m *Message) Info(str string, arg ...Any) *Message {
return m.log(LOG_INFO, str, arg...)
}
func (m *Message) WarnTimeNotValid(time Any, arg ...Any) bool {
return m.Warn(kit.Format(time) < m.Time(), ErrNotValid, kit.Simple(arg), time, m.Time(), logs.FileLineMeta(logs.FileLine(2)))
}
func (m *Message) Warn(err Any, arg ...Any) bool {
switch err := err.(type) {
case error:

View File

@ -112,6 +112,7 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message {
var v Any
switch k {
case "_target":
continue
case KEY, HASH:
if key != "" && key != FIELDS_DETAIL {
v = key