1
0
forked from x/icebergs
This commit is contained in:
IT 老营长 @云轩领航-创始人 2024-04-07 23:14:08 +08:00
parent 6154aa93aa
commit d0710dc9e2
16 changed files with 85 additions and 58 deletions

View File

@ -147,8 +147,9 @@ const (
CTX_SHY = "ctx_shy" CTX_SHY = "ctx_shy"
CTX_DEV = "ctx_dev" CTX_DEV = "ctx_dev"
CTX_DEV_IP = "ctx_dev_ip" CTX_DEV_IP = "ctx_dev_ip"
CTX_REPOS = "ctx_repos"
CTX_OPS = "ctx_ops" CTX_OPS = "ctx_ops"
CTX_REPOS = "ctx_repos"
CTX_NAME = "ctx_name"
CTX_DEMO = "ctx_demo" CTX_DEMO = "ctx_demo"
CTX_MAIL = "ctx_mail" CTX_MAIL = "ctx_mail"
CTX_ROOT = "ctx_root" CTX_ROOT = "ctx_root"

View File

@ -59,7 +59,7 @@ func _system_cmd(m *ice.Message, arg ...string) *exec.Cmd {
} }
} }
kit.For(env, func(k, v string) { cmd.Env = append(cmd.Env, kit.Format("%s=%s", k, v)) }) kit.For(env, func(k, v string) { cmd.Env = append(cmd.Env, kit.Format("%s=%s", k, v)) })
kit.If(len(cmd.Env) > 0, func() { m.Logs(EXEC, CMD_ENV, kit.Format(cmd.Env)) }) kit.If(len(cmd.Env) > 0 && m.IsDebug(), func() { m.Logs(EXEC, CMD_ENV, kit.Format(cmd.Env)) })
return cmd return cmd
} }
func _system_out(m *ice.Message, out string) io.Writer { func _system_out(m *ice.Message, out string) io.Writer {

View File

@ -9,6 +9,7 @@ import (
"shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/web/html"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
) )
@ -60,6 +61,7 @@ const (
ICONS = ice.CTX_ICONS ICONS = ice.CTX_ICONS
TRANS = ice.CTX_TRANS TRANS = ice.CTX_TRANS
TITLE = ice.CTX_TITLE TITLE = ice.CTX_TITLE
INPUT = html.INPUT
) )
const COMMAND = "command" const COMMAND = "command"

View File

@ -75,6 +75,7 @@ const (
TARGET = "target" TARGET = "target"
BINARY = "binary" BINARY = "binary"
SCRIPT = "script" SCRIPT = "script"
FORMAT = "format"
CLONE = "clone" CLONE = "clone"
REPOS = "repos" REPOS = "repos"

View File

@ -45,6 +45,7 @@ const (
SEND = "send" SEND = "send"
RECV = "recv" RECV = "recv"
ECHO = "echo" ECHO = "echo"
DONE = "done"
DIRECT = "direct" DIRECT = "direct"
) )

View File

@ -79,6 +79,8 @@ const (
VIEW = "view" VIEW = "view"
VALUE = "value" VALUE = "value"
INPUT = "input" INPUT = "input"
ICON = "icon"
ICONS = "icons"
OUTPUT = "output" OUTPUT = "output"
LAYOUT = "layout" LAYOUT = "layout"
RESIZE = "resize" RESIZE = "resize"

View File

@ -224,9 +224,7 @@ func init() {
mdb.Config(m, ice.MAIN, C(m.Option(ctx.INDEX))) mdb.Config(m, ice.MAIN, C(m.Option(ctx.INDEX)))
} }
}}, }},
mdb.ICONS: {Hand: func(m *ice.Message, arg ...string) { mdb.ICONS: {Hand: func(m *ice.Message, arg ...string) { mdb.Config(m, mdb.ICONS, arg[0]) }},
mdb.Config(m, mdb.ICONS, arg[0])
}},
tcp.HOST: {Help: "公网", Hand: func(m *ice.Message, arg ...string) { m.Echo(kit.Formats(PublicIP(m))) }}, tcp.HOST: {Help: "公网", Hand: func(m *ice.Message, arg ...string) { m.Echo(kit.Formats(PublicIP(m))) }},
cli.SYSTEM: {Help: "系统", Hand: func(m *ice.Message, arg ...string) { cli.Opens(m, "System Settings.app") }}, cli.SYSTEM: {Help: "系统", Hand: func(m *ice.Message, arg ...string) { cli.Opens(m, "System Settings.app") }},
cli.START: {Name: "start dev proto host port=9020 nodename username usernick", Hand: func(m *ice.Message, arg ...string) { cli.START: {Name: "start dev proto host port=9020 nodename username usernick", Hand: func(m *ice.Message, arg ...string) {
@ -264,7 +262,6 @@ func init() {
} }
}}, }},
}, gdb.EventsAction(SERVE_START), mdb.HashAction( }, gdb.EventsAction(SERVE_START), mdb.HashAction(
mdb.ICONS, ice.SRC_MAIN_ICO,
mdb.SHORT, mdb.NAME, mdb.FIELD, "time,status,name,proto,host,port"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) { mdb.SHORT, mdb.NAME, mdb.FIELD, "time,status,name,proto,host,port"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {
mdb.HashSelect(m, arg...).Action().StatusTimeCount(kit.Dict(ice.MAIN, mdb.Config(m, ice.MAIN))) mdb.HashSelect(m, arg...).Action().StatusTimeCount(kit.Dict(ice.MAIN, mdb.Config(m, ice.MAIN)))
}}, }},

View File

@ -83,6 +83,7 @@ func _space_fork(m *ice.Message) {
} }
args := kit.Simple(mdb.TYPE, m.Option(mdb.TYPE), mdb.NAME, name, mdb.TEXT, text, m.OptionSimple(mdb.ICONS, mdb.TIME, nfs.MODULE, nfs.VERSION, cli.DAEMON)) args := kit.Simple(mdb.TYPE, m.Option(mdb.TYPE), mdb.NAME, name, mdb.TEXT, text, m.OptionSimple(mdb.ICONS, mdb.TIME, nfs.MODULE, nfs.VERSION, cli.DAEMON))
args = append(args, aaa.USERNICK, m.Option(ice.MSG_USERNICK), aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERROLE, m.Option(ice.MSG_USERROLE)) args = append(args, aaa.USERNICK, m.Option(ice.MSG_USERNICK), aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERROLE, m.Option(ice.MSG_USERROLE))
args = append(args, cli.SYSTEM, m.Option(cli.GOOS))
args = append(args, ParseUA(m)...) args = append(args, ParseUA(m)...)
if c, e := websocket.Upgrade(m.W, m.R); !m.WarnNotValid(e) { if c, e := websocket.Upgrade(m.W, m.R); !m.WarnNotValid(e) {
gdb.Go(m, func() { gdb.Go(m, func() {
@ -100,13 +101,14 @@ func _space_fork(m *ice.Message) {
case WORKER: case WORKER:
defer gdb.EventDeferEvent(m, DREAM_OPEN, args)(DREAM_CLOSE, args) defer gdb.EventDeferEvent(m, DREAM_OPEN, args)(DREAM_CLOSE, args)
safe = true safe = true
m.Go(func() {
SpacePwd(m, name, kit.Path(""))
SpaceEvent(m, OPS_SERVER_OPEN, name, args...)
})
case SERVER: case SERVER:
defer gdb.EventDeferEvent(m, SPACE_OPEN, args)(SPACE_CLOSE, args) defer gdb.EventDeferEvent(m, SPACE_OPEN, args)(SPACE_CLOSE, args)
m.Go(func() { m.Go(func() {
m.Cmd(SPACE, name, cli.PWD, name, kit.Dict( SpacePwd(m, name, "")
mdb.ICONS, ice.Info.NodeIcon, mdb.TIME, ice.Info.Make.Time, nfs.MODULE, ice.Info.Make.Module, nfs.VERSION, ice.Info.Make.Versions(),
AGENT, "Go-http-client", cli.SYSTEM, runtime.GOOS,
))
SpaceEvent(m, OPS_SERVER_OPEN, name, args...) SpaceEvent(m, OPS_SERVER_OPEN, name, args...)
}) })
} }
@ -130,7 +132,7 @@ func _space_handle(m *ice.Message, safe bool, name string, c *websocket.Conn) {
kit.If(msg.Option(ice.MSG_USERROLE), func() { msg.Option(ice.MSG_USERROLE, aaa.VOID) }) kit.If(msg.Option(ice.MSG_USERROLE), func() { msg.Option(ice.MSG_USERROLE, aaa.VOID) })
} }
source, target := kit.Simple(msg.Optionv(ice.MSG_SOURCE), name), kit.Simple(msg.Optionv(ice.MSG_TARGET)) source, target := kit.Simple(msg.Optionv(ice.MSG_SOURCE), name), kit.Simple(msg.Optionv(ice.MSG_TARGET))
msg.Log(tcp.RECV, "%v->%v %v %v", source, target, msg.Detailv(), msg.FormatMeta()) msg.Log(kit.Select(tcp.RECV, tcp.ECHO, msg.Option(ice.MSG_HANDLE) == ice.TRUE), "%v->%v %v %v", source, target, msg.Detailv(), msg.FormatMeta())
if next := msg.Option(ice.MSG_TARGET); next == "" || len(target) == 0 { if next := msg.Option(ice.MSG_TARGET); next == "" || len(target) == 0 {
msg.Go(func() { msg.Go(func() {
if k := kit.Keys(msg.Option(ice.MSG_USERPOD), "_token"); msg.Option(k) != "" { if k := kit.Keys(msg.Option(ice.MSG_USERPOD), "_token"); msg.Option(k) != "" {
@ -175,23 +177,27 @@ func _space_domain(m *ice.Message) (link string) {
) )
} }
func _space_exec(m *ice.Message, name string, source, target []string, c *websocket.Conn) { func _space_exec(m *ice.Message, name string, source, target []string, c *websocket.Conn) {
m.Option(ice.MSG_HANDLE, ice.TRUE)
switch kit.Select("", m.Detailv(), 0) { switch kit.Select("", m.Detailv(), 0) {
case "": case "":
m.Warn(true, ice.ErrNotValid) m.Warn(true, ice.ErrNotValid)
return return
case cli.PWD: case cli.PWD:
if m.Option(mdb.ICONS) != "" && !kit.HasPrefix(m.Option(mdb.ICONS), nfs.PS, HTTP) {
m.Option(mdb.ICONS, kit.MergeURL2(SpideOrigin(m, name), "/require/"+m.Option(mdb.ICONS)))
}
mdb.HashModify(m, mdb.HASH, name, ParseUA(m), m.OptionSimple(mdb.ICONS, mdb.TIME, nfs.MODULE, nfs.VERSION, AGENT, cli.SYSTEM))
m.Push(mdb.LINK, m.MergePod(kit.Select("", source, -1))) m.Push(mdb.LINK, m.MergePod(kit.Select("", source, -1)))
SpaceEvent(m, OPS_ORIGIN_OPEN, name, kit.Simple(mdb.NAME, name, m.OptionSimple(mdb.ICONS, mdb.TIME, nfs.MODULE, nfs.VERSION, AGENT, cli.SYSTEM))...) if m.Option(cli.SYSTEM) == "" {
m.Optionv(ice.MSG_OPTION, []string{})
break
}
m.Option(mdb.ICONS, m.Resource(m.Option(mdb.ICONS), SpideOrigin(m, name)))
args := m.OptionSimple(mdb.ICONS, mdb.TIME, nfs.MODULE, nfs.VERSION, AGENT, cli.SYSTEM)
kit.If(name == ice.OPS, func() { args = append(args, m.OptionSimple(mdb.TEXT)...) })
mdb.HashModify(m, mdb.HASH, name, ParseUA(m), args)
SpaceEvent(m, OPS_ORIGIN_OPEN, name, kit.Simple(mdb.NAME, name, args)...)
default: default:
if m.IsErr() { if m.IsErr() {
return return
} }
m.OptionDefault(ice.MSG_COUNT, "0") m.Options(ice.MSG_ARGS, "", ice.MSG_COUNT, "0")
m.Option(ice.MSG_ARGS, "")
kit.If(m.Option(ice.MSG_DAEMON), func(p string) { kit.If(m.Option(ice.MSG_DAEMON), func(p string) {
m.Option(ice.MSG_DAEMON0, m.Option(ice.MSG_DAEMON)) m.Option(ice.MSG_DAEMON0, m.Option(ice.MSG_DAEMON))
m.Option(ice.MSG_DAEMON, kit.Keys(kit.Slice(kit.Reverse(kit.Simple(source)), 0, -1), p)) m.Option(ice.MSG_DAEMON, kit.Keys(kit.Slice(kit.Reverse(kit.Simple(source)), 0, -1), p))
@ -200,19 +206,18 @@ func _space_exec(m *ice.Message, name string, source, target []string, c *websoc
kit.If(aaa.Right(m, m.Detailv()), func() { m.TryCatch(true, func(_ *ice.Message) { m = m.Cmd() }) }) kit.If(aaa.Right(m, m.Detailv()), func() { m.TryCatch(true, func(_ *ice.Message) { m = m.Cmd() }) })
kit.If(m.Optionv(ice.MSG_ARGS) != nil, func() { m.Options(ice.MSG_ARGS, kit.Simple(m.Optionv(ice.MSG_ARGS))) }) kit.If(m.Optionv(ice.MSG_ARGS) != nil, func() { m.Options(ice.MSG_ARGS, kit.Simple(m.Optionv(ice.MSG_ARGS))) })
} }
m.Option(ice.MSG_HANDLE, ice.TRUE) defer m.Cost(kit.Format("%v->%v %v %v", source, target, m.Detailv(), m.FormatSize()))
if m.Option(ice.SPACE_NOECHO) == ice.TRUE { if m.Option(ice.SPACE_NOECHO) == ice.TRUE {
return return
} }
defer m.Cost(kit.Format("%v->%v %v %v", source, target, m.Detailv(), m.FormatSize()))
m.Options(ice.MSG_USERWEB, m.Optionv(ice.MSG_USERWEB), ice.MSG_USERPOD, m.Optionv(ice.MSG_USERPOD)) m.Options(ice.MSG_USERWEB, m.Optionv(ice.MSG_USERWEB), ice.MSG_USERPOD, m.Optionv(ice.MSG_USERPOD))
_space_echo(m.Set(ice.MSG_OPTS).Options(m.OptionSimple(ice.MSG_HANDLE, ice.LOG_DEBUG, ice.LOG_DISABLE, ice.LOG_TRACEID)), []string{}, kit.Reverse(kit.Simple(source)), c) _space_echo(m.Set(ice.MSG_OPTS).Options(m.OptionSimple(ice.MSG_HANDLE, ice.LOG_DEBUG, ice.LOG_DISABLE, ice.LOG_TRACEID)), []string{}, kit.Reverse(kit.Simple(source)), c)
} }
func _space_echo(m *ice.Message, source, target []string, c *websocket.Conn) { func _space_echo(m *ice.Message, source, target []string, c *websocket.Conn) {
defer func() { m.WarnNotValid(recover()) }() defer func() { m.WarnNotValid(recover()) }()
if m.Options(ice.MSG_SOURCE, source, ice.MSG_TARGET, target[1:]); !m.WarnNotValid(c.WriteMessage(1, []byte(m.FormatMeta()))) { if m.Options(ice.MSG_SOURCE, source, ice.MSG_TARGET, target[1:]); !m.WarnNotValid(c.WriteMessage(1, []byte(m.FormatsMeta(nil)))) {
if source != nil { if source != nil {
m.Log(kit.Select(tcp.SEND, tcp.ECHO, m.Option(ice.MSG_HANDLE) == ice.TRUE), "%v->%v %v %v", source, target, kit.ReplaceAll(kit.Format("%v", m.Detailv()), "\r\n", "\\r\\n", "\t", "\\t", "\n", "\\n"), m.FormatMeta()) m.Log(kit.Select(tcp.SEND, tcp.DONE, m.Option(ice.MSG_HANDLE) == ice.TRUE), "%v->%v %v %v", source, target, kit.ReplaceAll(kit.Format("%v", m.Detailv()), "\r\n", "\\r\\n", "\t", "\\t", "\n", "\\n"), m.FormatMeta())
} }
} }
} }
@ -306,6 +311,7 @@ func init() {
m.Push(mdb.ICONS, ice.Info.NodeIcon) m.Push(mdb.ICONS, ice.Info.NodeIcon)
m.Push(nfs.MODULE, ice.Info.Make.Module) m.Push(nfs.MODULE, ice.Info.Make.Module)
m.Push(nfs.VERSION, ice.Info.Make.Versions()) m.Push(nfs.VERSION, ice.Info.Make.Versions())
m.Push(nfs.PATHNAME, ice.Info.Pathname)
m.Push(ORIGIN, m.Option(ice.MSG_USERHOST)) m.Push(ORIGIN, m.Option(ice.MSG_USERHOST))
}}, }},
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) { mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
@ -354,7 +360,7 @@ func init() {
nfs.PS: {Hand: func(m *ice.Message, arg ...string) { _space_fork(m) }}, nfs.PS: {Hand: func(m *ice.Message, arg ...string) { _space_fork(m) }},
}, gdb.EventsAction(SPACE_LOGIN), mdb.HashAction(mdb.LIMIT, 1000, mdb.LEAST, 500, }, gdb.EventsAction(SPACE_LOGIN), mdb.HashAction(mdb.LIMIT, 1000, mdb.LEAST, 500,
mdb.SHORT, mdb.NAME, mdb.FIELD, "time,type,name,text,icons,module,version,agent,system,ip,usernick,username,userrole", mdb.SHORT, mdb.NAME, mdb.FIELD, "time,type,name,text,icons,module,version,agent,system,ip,usernick,username,userrole",
ctx.ACTION, OPEN, REDIAL, kit.Dict("a", 1000, "b", 100, "c", 1000), mdb.ICONS, ice.SRC_MAIN_ICO, ctx.ACTION, OPEN, REDIAL, kit.Dict("a", 1000, "b", 100, "c", 1000),
), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) { ), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {
if len(arg) < 2 { if len(arg) < 2 {
if len(arg) == 1 && strings.Contains(arg[0], nfs.PT) { if len(arg) == 1 && strings.Contains(arg[0], nfs.PT) {
@ -379,7 +385,7 @@ func init() {
} }
m.PushButton(kit.Select(OPEN, LOGIN, value[mdb.TYPE] == LOGIN), mdb.REMOVE) m.PushButton(kit.Select(OPEN, LOGIN, value[mdb.TYPE] == LOGIN), mdb.REMOVE)
}) })
m.Sort("", kit.Simple(aaa.LOGIN, WEIXIN, PORTAL, WORKER, SERVER, ORIGIN)) m.Action(html.FILTER).Sort("", kit.Simple(aaa.LOGIN, WEIXIN, PORTAL, WORKER, SERVER, ORIGIN))
} else { } else {
if kit.IsIn(arg[0], "", ice.CONTEXTS) { if kit.IsIn(arg[0], "", ice.CONTEXTS) {
m.Cmdy(arg[1:]) m.Cmdy(arg[1:])
@ -484,10 +490,21 @@ func PodCmd(m *ice.Message, key string, arg ...string) bool {
func SpaceName(name string) string { func SpaceName(name string) string {
return kit.ReplaceAll(name, nfs.DF, "_", nfs.PS, "_", nfs.PT, "_", "[", "_", "]", "_") return kit.ReplaceAll(name, nfs.DF, "_", nfs.PS, "_", nfs.PT, "_", "[", "_", "]", "_")
} }
func SpacePwd(m *ice.Message, name, text string) {
m.Optionv(ice.MSG_OPTS, m.OptionSimple(ice.MSG_USERROLE, ice.MSG_USERNAME))
m.Cmd(SPACE, name, cli.PWD, name, kit.Dict(
ice.SPACE_NOECHO, ice.TRUE,
mdb.ICONS, ice.Info.NodeIcon, mdb.TEXT, text, AGENT, "Go-http-client", cli.SYSTEM, runtime.GOOS,
mdb.TIME, ice.Info.Make.Time, nfs.MODULE, ice.Info.Make.Module, nfs.VERSION, ice.Info.Make.Versions(),
))
}
func SpaceEvent(m *ice.Message, event, skip string, arg ...string) { func SpaceEvent(m *ice.Message, event, skip string, arg ...string) {
m.Optionv(ice.MSG_OPTS, m.OptionSimple(ice.MSG_USERROLE, ice.MSG_USERNAME))
m.Cmds(SPACE).Table(func(value ice.Maps) { m.Cmds(SPACE).Table(func(value ice.Maps) {
if kit.IsIn(value[mdb.TYPE], WORKER) && value[mdb.NAME] != skip { if kit.IsIn(value[mdb.TYPE], WORKER) && value[mdb.NAME] != skip {
m.Cmd(SPACE, value[mdb.NAME], gdb.EVENT, gdb.HAPPEN, gdb.EVENT, event, arg, kit.Dict(ice.MSG_USERROLE, aaa.TECH)) m.Cmd(SPACE, value[mdb.NAME], gdb.EVENT, gdb.HAPPEN, gdb.EVENT, event, arg, kit.Dict(
ice.MSG_USERROLE, aaa.TECH, ice.SPACE_NOECHO, ice.TRUE,
))
} }
}) })
m.Cmd(gdb.EVENT, gdb.HAPPEN, gdb.EVENT, event, arg, kit.Dict(ice.MSG_USERROLE, aaa.TECH)) m.Cmd(gdb.EVENT, gdb.HAPPEN, gdb.EVENT, event, arg, kit.Dict(ice.MSG_USERROLE, aaa.TECH))

View File

@ -49,7 +49,7 @@ func _publish_contexts(m *ice.Message, arg ...string) {
m.OptionDefault(cli.CTX_CLI, "temp=$(mktemp); if curl -h &>/dev/null; then curl -o $temp -fsSL $ctx_dev; else wget -O $temp -q $ctx_dev; fi; source $temp") m.OptionDefault(cli.CTX_CLI, "temp=$(mktemp); if curl -h &>/dev/null; then curl -o $temp -fsSL $ctx_dev; else wget -O $temp -q $ctx_dev; fi; source $temp")
m.OptionDefault(cli.CTX_ARG, kit.JoinCmdArgs(aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERNICK, m.Option(ice.MSG_USERNICK), aaa.LANGUAGE, m.Option(ice.MSG_LANGUAGE))) m.OptionDefault(cli.CTX_ARG, kit.JoinCmdArgs(aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERNICK, m.Option(ice.MSG_USERNICK), aaa.LANGUAGE, m.Option(ice.MSG_LANGUAGE)))
m.Option(web.DOMAIN, strings.Split(m.Option(web.DOMAIN), "?")[0]) m.Option(web.DOMAIN, strings.Split(m.Option(web.DOMAIN), "?")[0])
msg := web.AdminCmd(m, web.SPACE, "info") msg := web.AdminCmd(m, web.SPACE, ice.INFO)
for _, k := range kit.Default(arg, ice.APP) { for _, k := range kit.Default(arg, ice.APP) {
env := []string{} env := []string{}
switch k { switch k {
@ -64,18 +64,18 @@ func _publish_contexts(m *ice.Message, arg ...string) {
env = append(env, cli.CTX_REPOS, m.Option(nfs.SOURCE)) env = append(env, cli.CTX_REPOS, m.Option(nfs.SOURCE))
fallthrough fallthrough
case nfs.BINARY, ice.APP: case nfs.BINARY, ice.APP:
if host := msg.Append("hostport"); m.Option(web.DOMAIN) != host { if host := msg.Append(web.ORIGIN); m.Option(web.DOMAIN) != host {
env = append(env, cli.CTX_DEV_IP, strings.Split(host, "?")[0]) env = append(env, cli.CTX_DEV_IP, strings.Split(host, "?")[0])
} }
if m.Option(ice.MSG_USERPOD) != "" { if m.Option(ice.MSG_USERPOD) != "" {
env = append(env, cli.CTX_POD, m.Option(ice.MSG_USERPOD)) env = append(env, cli.CTX_POD, m.Option(ice.MSG_USERPOD))
} else if name := msg.Append("pathname"); !kit.IsIn(name, path.Base(m.Option(nfs.SOURCE)), ice.CONTEXTS) { } else if name := msg.Append(nfs.PATHNAME); !kit.IsIn(name, path.Base(m.Option(nfs.SOURCE)), ice.CONTEXTS) {
env = append(env, "ctx_name", name) env = append(env, cli.CTX_NAME, name)
} }
case cli.CURL, cli.WGET: case cli.CURL, cli.WGET:
} }
kit.If(len(env) > 0, func() { m.Options(cli.CTX_ENV, lex.SP+kit.JoinKV(mdb.EQ, lex.SP, env...)) }) kit.If(len(env) > 0, func() { m.Options(cli.CTX_ENV, lex.SP+kit.JoinKV(mdb.EQ, lex.SP, env...)) })
if template := strings.TrimSpace(nfs.Template(m, kit.Keys(k, SH))); m.Option("format") == "raw" { if template := strings.TrimSpace(nfs.Template(m, kit.Keys(k, SH))); m.Option(nfs.FORMAT) == "raw" {
m.Echo(template) m.Echo(template)
} else { } else {
m.EchoScript(template) m.EchoScript(template)

View File

@ -96,6 +96,7 @@ type info struct {
} }
var Info = info{ var Info = info{
NodeIcon: SRC_MAIN_ICO,
Localhost: true, Localhost: true,
File: Maps{}, File: Maps{},

View File

@ -224,7 +224,7 @@ func (m *Message) FormatsMeta(w io.Writer, arg ...string) (res string) {
defer func() { res = buf.String() }() defer func() { res = buf.String() }()
w = buf w = buf
} }
kit.For(m.value(MSG_OPTION), func(i int, k string) { kit.For(m.value(MSG_OPTION), func(k string, i int) {
ls := m.value(k) ls := m.value(k)
kit.If(len(ls) == 0 || len(ls) == 1 && ls[0] == "", func() { m.index(MSG_OPTION, i, "") }) kit.If(len(ls) == 0 || len(ls) == 1 && ls[0] == "", func() { m.index(MSG_OPTION, i, "") })
}) })

View File

@ -498,6 +498,7 @@ func init() {
default: default:
switch arg[0] { switch arg[0] {
case MESSAGE: case MESSAGE:
m.SetAppend()
ls := kit.Split(m.Option(nfs.FILE), " /") ls := kit.Split(m.Option(nfs.FILE), " /")
m.Push(arg[0], kit.Select("", ls, -2)) m.Push(arg[0], kit.Select("", ls, -2))
m.Push(arg[0], kit.Join(kit.Slice(ls, -1), nfs.PS)) m.Push(arg[0], kit.Join(kit.Slice(ls, -1), nfs.PS))

View File

@ -13,7 +13,6 @@ import (
"shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/web" "shylinux.com/x/icebergs/base/web"
"shylinux.com/x/icebergs/base/web/html"
"shylinux.com/x/icebergs/core/code" "shylinux.com/x/icebergs/core/code"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
) )
@ -32,7 +31,8 @@ const STATUS = "status"
func init() { func init() {
Index.MergeCommands(ice.Commands{ Index.MergeCommands(ice.Commands{
STATUS: {Name: "status repos:text auto", Help: "源代码", Icon: "git.png", Role: aaa.VOID, Meta: kit.Dict( STATUS: {Name: "status repos:text auto", Help: "源代码", Icon: "git.png", Role: aaa.VOID, Meta: kit.Dict(
ice.CTX_TRANS, kit.Dict(html.INPUT, kit.Dict("actions", "操作", "message", "信息", "remote", "远程库")), ctx.ICONS, kit.Dict("message", "bi bi-info-square"),
ctx.TRANS, kit.Dict(ctx.INPUT, kit.Dict("actions", "操作", "message", "信息", "remote", "远程库")),
), Actions: ice.MergeActions(ice.Actions{ ), Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: web.DreamWhiteHandle}, ice.CTX_INIT: {Hand: web.DreamWhiteHandle},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {

View File

@ -25,10 +25,11 @@ import (
) )
const ( const (
RELAY = "relay" RELAY = "relay"
SSH_RELAY = "ssh.relay" SSH_RELAY = "ssh.relay"
SRC_RELAY_GO = "src/relay.go" SRC_RELAY_GO = "src/relay.go"
CONTEXTS = "contexts/" SSH_CONNECT = "ssh.connect"
SSH_AUTHORIZED = ".ssh/authorized_keys"
INSTALL_SH = "install.sh" INSTALL_SH = "install.sh"
UPGRADE_SH = "upgrade.sh" UPGRADE_SH = "upgrade.sh"
@ -66,23 +67,21 @@ type relay struct {
field string `data:"time,icons,machine,username,host,port,portal,dream,module,version,commitTime,compileTime,bootTime,go,git,package,shell,kernel,arch,vcpu,ncpu,mhz,mem,disk,network,listen,socket,proc,vendor"` field string `data:"time,icons,machine,username,host,port,portal,dream,module,version,commitTime,compileTime,bootTime,go,git,package,shell,kernel,arch,vcpu,ncpu,mhz,mem,disk,network,listen,socket,proc,vendor"`
create string `name:"create host* port=22 username=root machine icons"` create string `name:"create host* port=22 username=root machine icons"`
upgrade string `name:"upgrade machine"` upgrade string `name:"upgrade machine"`
stats string `name:"stats machine" help:"采集" icon:"bi bi-card-list"` stats string `name:"stats machine" icon:"bi bi-card-list"`
publish string `name:"publish" help:"发布" icon:"bi bi-send-check"` publish string `name:"publish" icon:"bi bi-send-check"`
forEach string `name:"forEach machine cmd*:textarea=pwd"` forEach string `name:"forEach machine cmd*:textarea=pwd"`
forFlow string `name:"forFlow machine cmd*:textarea=pwd"` forFlow string `name:"forFlow machine cmd*:textarea=pwd"`
list string `name:"list machine auto" help:"机器" icon:"relay.png"` list string `name:"list machine auto" help:"机器" icon:"relay.png"`
install string `name:"install dream portal nodename dev" help:"安装"` install string `name:"install dream portal nodename dev"`
pushbin string `name:"pushbin dream portal nodename dev" help:"部署" icon:"bi bi-box-arrow-in-up"` pushbin string `name:"pushbin dream portal nodename dev" icon:"bi bi-box-arrow-in-up"`
adminCmd string `name:"adminCmd cmd" help:"命令" icon:"bi bi-terminal-plus"` adminCmd string `name:"adminCmd cmd" icon:"bi bi-terminal-plus"`
pushkey string `name:"pushkey" help:"授权" icon:"bi bi-person-fill-up"` pushkey string `name:"pushkey" icon:"bi bi-person-fill-up"`
status string `name:"status" help:"源码"`
spide string `name:"spide" help:"连接"`
} }
func (s relay) Init(m *ice.Message, arg ...string) { func (s relay) Init(m *ice.Message, arg ...string) {
s.Hash.Init(m, arg...) s.Hash.Init(m, arg...)
xterm.AddCommand(RELAY, func(m *icebergs.Message, arg ...string) (xterm.XTerm, error) { xterm.AddCommand(RELAY, func(m *icebergs.Message, arg ...string) (xterm.XTerm, error) {
m.Cmd("ssh.connect", tcp.DIAL, mdb.NAME, m.Option(mdb.NAME, arg[1]), arg) m.Cmd(SSH_CONNECT, tcp.DIAL, mdb.NAME, m.Option(mdb.NAME, arg[1]), arg)
return ssh.NewSession(m, arg[1]) return ssh.NewSession(m, arg[1])
}) })
} }
@ -269,7 +268,7 @@ func (s relay) Pushbin(m *ice.Message, arg ...string) {
dream := m.DreamPath(m.Option(web.DREAM)) dream := m.DreamPath(m.Option(web.DREAM))
m.Options(nfs.FROM, path.Join(dream, ice.USR_PUBLISH+bin), nfs.PATH, path.Base(dream), nfs.FILE, ice.BIN_ICE_BIN) m.Options(nfs.FROM, path.Join(dream, ice.USR_PUBLISH+bin), nfs.PATH, path.Base(dream), nfs.FILE, ice.BIN_ICE_BIN)
if m.Cmd(SSH_TRANS, tcp.SEND); m.OptionDefault(web.PORTAL, tcp.PORT_9020) == tcp.PORT_443 { if m.Cmd(SSH_TRANS, tcp.SEND); m.OptionDefault(web.PORTAL, tcp.PORT_9020) == tcp.PORT_443 {
msg := m.Cmd("aaa.cert", mdb.CREATE, m.Option(tcp.HOST)) msg := m.Cmd(aaa.CERT, mdb.CREATE, m.Option(tcp.HOST))
m.Cmd(SSH_TRANS, tcp.SEND, nfs.FROM, msg.Append(ssh.PEM), nfs.FILE, nfs.ETC_CERT_PEM) m.Cmd(SSH_TRANS, tcp.SEND, nfs.FROM, msg.Append(ssh.PEM), nfs.FILE, nfs.ETC_CERT_PEM)
m.Cmd(SSH_TRANS, tcp.SEND, nfs.FROM, msg.Append(ssh.KEY), nfs.FILE, nfs.ETC_CERT_KEY) m.Cmd(SSH_TRANS, tcp.SEND, nfs.FROM, msg.Append(ssh.KEY), nfs.FILE, nfs.ETC_CERT_KEY)
} }
@ -291,8 +290,8 @@ func (s relay) Spide(m *ice.Message, arg ...string) {
}) })
} }
func (s relay) Pushkey(m *ice.Message, arg ...string) { func (s relay) Pushkey(m *ice.Message, arg ...string) {
p := kit.Format("/home/%s/.ssh/authorized_keys", m.Option(aaa.USERNAME)) p := kit.Format("/home/%s/"+SSH_AUTHORIZED, m.Option(aaa.USERNAME))
kit.If(m.Option(aaa.USERNAME) == aaa.ROOT, func() { p = kit.Format("/root/.ssh/authorized_keys") }) kit.If(m.Option(aaa.USERNAME) == aaa.ROOT, func() { p = kit.Format("/root/" + SSH_AUTHORIZED) })
list := kit.Split(m.AdminCmdx(web.SPACE, m.Option(MACHINE), nfs.CAT, p), lex.NL, lex.NL) list := kit.Split(m.AdminCmdx(web.SPACE, m.Option(MACHINE), nfs.CAT, p), lex.NL, lex.NL)
if key := ssh.PublicKey(m.Message); !kit.IsIn(key, list...) { if key := ssh.PublicKey(m.Message); !kit.IsIn(key, list...) {
m.AdminCmd(web.SPACE, m.Option(MACHINE), nfs.PUSH, p, key) m.AdminCmd(web.SPACE, m.Option(MACHINE), nfs.PUSH, p, key)
@ -380,20 +379,20 @@ func (s relay) param(m *ice.Message, arg ...string) string {
func (s relay) CmdArgs(m *ice.Message, init string, arg ...string) string { func (s relay) CmdArgs(m *ice.Message, init string, arg ...string) string {
kit.If(m.Option(web.PORTAL) != "" && init == "", func() { init = kit.Format("%q", "cd "+path.Base(m.DreamPath(m.Option(web.DREAM)))) }) kit.If(m.Option(web.PORTAL) != "" && init == "", func() { init = kit.Format("%q", "cd "+path.Base(m.DreamPath(m.Option(web.DREAM)))) })
return strings.TrimPrefix(os.Args[0], kit.Path("")+nfs.PS) + " " + kit.JoinCmds(kit.Simple( return strings.TrimPrefix(os.Args[0], kit.Path("")+nfs.PS) + " " + kit.JoinCmds(kit.Simple(
"ssh.connect", tcp.OPEN, ssh.AUTHFILE, "", m.OptionSimple(aaa.USERNAME, tcp.HOST, tcp.PORT), ice.INIT, init)...) SSH_CONNECT, tcp.OPEN, ssh.AUTHFILE, "", m.OptionSimple(aaa.USERNAME, tcp.HOST, tcp.PORT), ice.INIT, init)...)
} }
type Relay struct { type Relay struct {
relay relay
pushbin string `name:"pushbin dream param='forever start' dev portal nodename" help:"部署" icon:"bi bi-box-arrow-in-up"` pushbin string `name:"pushbin dream param='forever start' dev portal nodename" icon:"bi bi-box-arrow-in-up"`
} }
func (s Relay) Cmds(m *ice.Message, host string, cmds string) *ice.Message { func (s Relay) Cmds(m *ice.Message, host string, cmds string) *ice.Message {
return m.Cmd(cli.SYSTEM, os.Args[0], "ssh.connect", tcp.OPEN, ssh.AUTHFILE, "", aaa.USERNAME, aaa.ROOT, tcp.HOST, host, tcp.PORT, tcp.PORT_22, ctx.CMDS, cmds) return m.Cmd(cli.SYSTEM, os.Args[0], SSH_CONNECT, tcp.OPEN, ssh.AUTHFILE, "", aaa.USERNAME, aaa.ROOT, tcp.HOST, host, tcp.PORT, tcp.PORT_22, ctx.CMDS, cmds)
} }
func (s Relay) CmdsWait(m *ice.Message, host string, cmds string, res string) bool { func (s Relay) CmdsWait(m *ice.Message, host string, cmds string, res string) bool {
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
if strings.TrimSpace(s.Cmds(m.Sleep("3s"), host, cmds).Result()) == res { if strings.TrimSpace(s.Cmds(m.Sleep(cli.TIME_3s), host, cmds).Result()) == res {
return true return true
} }
} }

View File

@ -1,4 +1,9 @@
{ {
"stats": "采集",
"spide": "连接",
"adminCmd": "命令",
"pushbin": "部署",
"pushkey": "授权",
"input": { "input": {
"machine": "机器", "machine": "机器",
"package": "软件包", "package": "软件包",

10
type.go
View File

@ -342,11 +342,11 @@ func (m *Message) Search(key string, cb Any) *Message {
} }
key = ls[len(ls)-1] key = ls[len(ls)-1]
} else if ctx, ok := Info.Index[key].(*Context); ok { } else if ctx, ok := Info.Index[key].(*Context); ok {
if _, ok := m.target.Commands[key]; ok { // if _, ok := m.target.Commands[key]; ok {
p = m.target // p = m.target
} else { // } else {
p = ctx p = ctx
} // }
} else { } else {
p = m.target p = m.target
} }